Mercurial > ~darius > hgwebdir.cgi > mikmod
changeset 10:55420dceb8e0
Initial entry of mikmod into the CVS tree.
author | darius |
---|---|
date | Fri, 23 Jan 1998 16:05:11 +0000 |
parents | 990c9dadb348 |
children | d5cb2cfc8eca |
files | include/getopt.h include/mikmod.h include/mmio.h include/ptform.h include/tdefs.h include/timer.h mmio/mmalloc.c mmio/mmerror.c mmio/mmio.c |
diffstat | 9 files changed, 2162 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/getopt.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,78 @@ + +#ifndef _GETOPT_H_ +#define _GETOPT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// ================ +// GETOPT.C Defines +// ================ + +/* + Types: + + P_BOOLEAN : Looks for a + or - immidiately after the option. + If none found (space or other option), -1 is passed. + + P_NUMVALUE : Grabs the value after the option (whitespace ignored). + If no value is given, -1 is passed. + + P_STRING : Grabs the string after the option (leading whitespace + is ignored). If no string was present, NULL is returned. + + Notes: + + A filename or string is normally terminated by a space (always a single + word long). If a filename or string is enclosed in quotations ("blah + blah"), then the string is not terminated until the closing quote is + encountered. + +*/ + +typedef struct FILESTACK +{ struct FILESTACK *prev,*next; + CHAR *path; // full path, including filename + ULONG size; // Size of the file +} FILESTACK; + + +typedef struct P_OPTION +{ CHAR *token; // option token (string) + UBYTE type; // type of option +} P_OPTION; + + +typedef struct P_PARSE +{ int num; // number of options + struct P_OPTION *option; // array of options +} P_PARSE; + + +typedef union P_VALUE +{ SLONG number; // numeric return value + CHAR *text; // string return value +} P_VALUE; + +#define P_STRING 32 +#define P_BOOLEAN 64 +#define P_NUMVALUE 128 + +#define EX_FULLSORT 0 +#define EX_FILESORT 1 + +int ngetopt(CHAR *token, P_PARSE *parse, int argc, CHAR *argv[], void (*post)(int, P_VALUE *)); +BOOL ex_init(CHAR *dir, CHAR *filemask, int sort); +void ex_exit(void); + +extern FILESTACK *filestack; +extern BOOL sortbydir; // set this to have getopt to catagorize filenames + // by the way they are given on the command line. + +#ifdef __cplusplus +} +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mikmod.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,415 @@ + +#ifndef MIKMOD_H +#define MIKMOD_H + +#include "mmio.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define MUTE_EXCLUSIVE 32000 +#define MUTE_INCLUSIVE 32001 + +#define PAN_LEFT 0 +#define PAN_CENTER 128 +#define PAN_RIGHT 255 +#define PAN_SURROUND 512 // panning value for Dolby Surround + + +#define MikMod_RegisterDriver(x) MD_RegisterDriver(&x) +#define MikMod_RegisterLoader(x) ML_RegisterLoader(&x) +#define MikMod_RegisterErrorHandler(x) _mm_RegisterErrorHandler(x) + + +// The following #define macros are for retaining API compatiability +// with the beta version of MikMod 3.0, and are TEMPORARY! They WILL +// be removed in the future! + +#define MD_RegisterPlayer(x) MikMod_RegisterPlayer(x) +#define MD_Init MikMod_Init +#define MD_Exit MikMod_Exit +#define MD_Update MikMod_Update +#define ML_Free(x) MikMod_FreeSong(x) +#define MD_SetNumChannels(x,y) MikMod_SetNumVoices(x,y) +#define MD_SetNumVoices(x,y) MikMod_SetNumVoices(x,y) +#define MD_PlayStart MikMod_EnableOutput +#define MD_PlayStop MikMod_DisableOutput + +#define MD_VoiceSetVolume(x,y) Voice_SetVolume(x,y) +#define MD_VoiceSetFrequency(x,y) Voice_SetFrequency(x,y) +#define MD_VoiceSetPanning(x,y) Voice_SetPanning(x,y) +#define MD_VoicePlay(x,y,z) Voice_Play(x,y,z) +#define MD_VoiceStop(x) Voice_Stop(x) +#define MD_VoiceReleaseSustain(x) Voice_ReleaseSustain(x) +#define MD_VoiceStopped(x) Voice_Stopped(x) +#define MD_VoiceGetPosition(x) Voice_GetPosition(x) +#define MD_VoiceRealVolume(x) Voice_RealVolume(x) + + +#define SFX_CRITICAL 1 + + +/************************************************************************** +****** mikmod types: ****************************************************** +**************************************************************************/ + +// Sample format [loading and in-memory] flags: +#define SF_16BITS 1 +#define SF_SIGNED 2 +#define SF_STEREO 4 +#define SF_DELTA 8 +#define SF_BIG_ENDIAN 16 + +// General Playback flags + +#define SF_LOOP 32 +#define SF_BIDI 64 +#define SF_SUSTAIN 128 +#define SF_REVERSE 256 + +// Module-only Playback Flags + +#define SF_OWNPAN 512 +#define SF_UST_LOOP 1024 + + +typedef struct SAMPLE +{ ULONG speed; // Base playing speed/frequency of note (Middle C in player) + UBYTE volume; // volume 0-64 + UWORD panning; // panning (0-255 or PAN_SURROUND) + ULONG length; // length of sample (in samples!) + ULONG loopstart; // repeat position (relative to start, in samples) + ULONG loopend; // repeat end + ULONG susbegin; // sustain loop begin (in samples) \ Not Supported + ULONG susend; // sustain loop end / Yet! + + UWORD flags; // sample format in memory + +// Variables used by the module player only! (ignored for sound effects) + + UBYTE globvol; // global volume + UBYTE vibflags; // autovibrato flag stuffs + UBYTE vibtype; // Vibratos moved from INSTRUMENT to SAMPLE + UBYTE vibsweep; + UBYTE vibdepth; + UBYTE vibrate; + + CHAR *samplename; // name of the sample + +// Values used internally only (not saved in disk formats) + + UWORD avibpos; // autovibrato pos [player use] + UBYTE divfactor; // for sample scaling (maintains proper period slides) + ULONG seekpos; // seek position in file + SWORD handle; // sample handle used by individual drivers +} SAMPLE; + + + +// --> Struct : SAMPLOAD +// This is a handle of sorts attached to any sample registered with +// SL_RegisterSample. Generally, this only need be used or changed by the +// loaders and drivers of mikmod. + +typedef struct SAMPLOAD +{ struct SAMPLOAD *next; + + ULONG length; // length of sample (in samples!) + ULONG loopstart; // repeat position (relative to start, in samples) + ULONG loopend; // repeat end + + UWORD infmt, outfmt; + int scalefactor; + SAMPLE *sample; + FILE *fp; +} SAMPLOAD; + +extern void SL_HalveSample(SAMPLOAD *s); +extern void SL_Sample8to16(SAMPLOAD *s); +extern void SL_Sample16to8(SAMPLOAD *s); +extern void SL_SampleSigned(SAMPLOAD *s); +extern void SL_SampleUnsigned(SAMPLOAD *s); +extern BOOL SL_LoadSamples(void); // Returns 1 on error! +extern SAMPLOAD *SL_RegisterSample(SAMPLE *s, int type, FILE *fp); // Returns 1 on error! +extern void SL_Load(void *buffer, SAMPLOAD *smp, int length); +extern BOOL SL_Init(SAMPLOAD *s); +extern void SL_Exit(SAMPLOAD *s); + + +/************************************************************************** +****** Wavload stuff: ***************************************************** +**************************************************************************/ + +SAMPLE *WAV_LoadFP(FILE *fp); +SAMPLE *WAV_LoadFN(CHAR *filename); +void WAV_Free(SAMPLE *si); + + +#include "ptform.h" + + +/************************************************************************** +****** Driver stuff: ****************************************************** +**************************************************************************/ + +// max. number of handles a driver has to provide. (not strict) + +#define MAXSAMPLEHANDLES 384 + + +enum +{ MD_MUSIC = 0, + MD_SNDFX +}; + +enum +{ MD_HARDWARE = 0, + MD_SOFTWARE +}; + + +// possible mixing mode bits: +// -------------------------- +// These take effect only after MikMod_Init or MikMod_Reset. + +#define DMODE_16BITS 1 // enable 16 bit output +#define DMODE_SURROUND 2 // enable Dolby surround sound (not yet supported) +#define DMODE_SOFT_SNDFX 4 // Process sound effects via software mixer (not yet supported) +#define DMODE_SOFT_MUSIC 8 // Process music via software mixer (not yet supported) + +// These take effect immidiately. + +#define DMODE_STEREO 16 // enable stereo output +#define DMODE_REVERSE 32 // reverse stereo +#define DMODE_INTERP 64 // enable interpolation (not yet supported) + + +// driver structure: + +typedef struct MDRIVER +{ struct MDRIVER *next; + CHAR *Name; + CHAR *Version; + UBYTE HardVoiceLimit, // Limit of hardware mixer voices for this driver + SoftVoiceLimit; // Limit of software mixer voices for this driver + + BOOL (*IsPresent) (void); + SWORD (*SampleLoad) (SAMPLOAD *s, int type, FILE *fp); + void (*SampleUnLoad) (SWORD handle); + ULONG (*FreeSampleSpace) (int type); + ULONG (*RealSampleLength) (int type, SAMPLE *s); + BOOL (*Init) (void); + void (*Exit) (void); + BOOL (*Reset) (void); + BOOL (*SetNumVoices) (void); + BOOL (*PlayStart) (void); + void (*PlayStop) (void); + void (*Update) (void); + void (*VoiceSetVolume) (UBYTE voice, UWORD vol); + void (*VoiceSetFrequency) (UBYTE voice, ULONG frq); + void (*VoiceSetPanning) (UBYTE voice, ULONG pan); + void (*VoicePlay) (UBYTE voice, SWORD handle, ULONG start, ULONG size, ULONG reppos, ULONG repend, UWORD flags); + void (*VoiceStop) (UBYTE voice); + BOOL (*VoiceStopped) (UBYTE voice); + void (*VoiceReleaseSustain)(UBYTE voice); + SLONG (*VoiceGetPosition) (UBYTE voice); + ULONG (*VoiceRealVolume) (UBYTE voice); + + BOOL (*StreamInit) (ULONG speed, UWORD flags); + void (*StreamExit) (void); + void (*StreamSetSpeed) (ULONG speed); + SLONG (*StreamGetPosition) (void); + void (*StreamLoadFP) (FILE *fp); +} MDRIVER; + + +// These variables can be changed at ANY time and results +// will be immidiate: + +extern UBYTE md_bpm; // current song / hardware BPM rate +extern UBYTE md_volume; // Global sound volume (0-128) +extern UBYTE md_musicvolume; // volume of song +extern UBYTE md_sndfxvolume; // volume of sound effects +extern UBYTE md_reverb; // 0 = none; 15 = chaos +extern UBYTE md_pansep; // 0 = mono; 128 == 100% (full left/right) + + +// The variables below can be changed at any time, but changes will +// not be implimented until MikMod_Reset is called. A call to +// MikMod_Reset may result in a skip or pop in audio (depending on +// the soundcard driver and the settings changed). + +extern UWORD md_device; // Device. 0 = autodetect, other # depend on driver register order. +extern UWORD md_mixfreq; // mixing frequency. Valid 5000 -> 44100 +extern UWORD md_dmabufsize; // DMA buffer size. Valid 512 -> 32000 +extern UWORD md_mode; // Mode. See DMODE_? flags above + + +// Variables below can be changed via MD_SetNumVoices at any time. +// However, a call to MD_SetNumVoicess while the driver +// is active will cause the sound to skip slightly. + +extern UBYTE md_numchn, // number of song + sound effects voices + md_sngchn, // number of song voices + md_sfxchn, // number of sound effects voices + md_hardchn, // number of hardware mixed voices + md_softchn; // number of software mixed voices + + +// Following variables should not be changed! +extern MDRIVER *md_driver; // Current driver in use. See MDRIVER struct + // above for structure info contents. + +// This is for use by the hardware drivers only. It points to the +// registered tickhandler function. +extern void (*md_player)(void); + + +// main driver prototypes: + +extern void MikMod_RegisterAllDrivers(void); +extern void MikMod_RegisterAllLoaders(void); + +extern BOOL MikMod_Init(void); +extern void MikMod_Exit(void); +extern BOOL MikMod_Reset(void); +extern int MikMod_PlaySample(SAMPLE *s, ULONG start, UBYTE flags); +extern BOOL MikMod_SetNumVoices(int music, int sndfx); +extern BOOL MikMod_Active(void); +extern BOOL MikMod_EnableOutput(void); +extern void MikMod_DisableOutput(void); +extern void MikMod_RegisterPlayer(void (*plr)(void)); +extern void MikMod_Update(void); + +extern void Voice_SetVolume(int voice, UWORD ivol); +extern void Voice_SetFrequency(int voice, ULONG frq); +extern void Voice_SetPanning(int voice, ULONG pan); +extern void Voice_Play(int voice,SAMPLE *s, ULONG start); +extern void Voice_Stop(int voice); +extern void Voice_ReleaseSustain(int voice); +extern BOOL Voice_Stopped(int voice); +extern SLONG Voice_GetPosition(int voice); +extern ULONG Voice_RealVolume(int voice); + +extern void MD_InfoDriver(void); +extern void MD_RegisterDriver(MDRIVER *drv); +extern SWORD MD_SampleLoad(SAMPLOAD *s, int type, FILE *fp); +extern void MD_SampleUnLoad(SWORD handle); +extern void MD_SetBPM(UBYTE bpm); +extern ULONG MD_SampleSpace(int type); +extern ULONG MD_SampleLength(int type, SAMPLE *s); + +// Declare external drivers: + +extern MDRIVER drv_awe; // experimental SB-AWE driver +extern MDRIVER drv_gus; // gravis ultrasound driver [hardware / software mixing] +extern MDRIVER drv_gus2; // gravis ultrasound driver [hardware mixing only] +extern MDRIVER drv_sb; // soundblaster 1.5 / 2.0 DSP driver +extern MDRIVER drv_sbpro; // soundblaster Pro DSP driver +extern MDRIVER drv_sb16; // soundblaster 16 DSP driver +extern MDRIVER drv_ss; // ensoniq soundscape driver +extern MDRIVER drv_pas; // PAS16 driver +extern MDRIVER drv_wss; // Windows Sound System driver +extern MDRIVER drv_nos; // nosound driver +extern MDRIVER drv_raw; // raw file output driver [music.raw] +extern MDRIVER drv_wav; // RIFF WAVE file output driver [music.wav] + +extern MDRIVER drv_w95; // win95 driver +extern MDRIVER drv_oss; // linux voxware driver +extern MDRIVER drv_AF; // Dec Alpha AudioFile driver +extern MDRIVER drv_sun; // Sun driver +extern MDRIVER drv_os2; // Os2 driver +extern MDRIVER drv_hp; // HP-UX /dev/audio driver +extern MDRIVER drv_aix; // AIX audio-device driver +extern MDRIVER drv_sgi; // SGI audio-device driver +extern MDRIVER drv_tim; // timing driver +extern MDRIVER drv_ultra; // ultra driver for linux + + +/************************************************************************** +****** Streaming Audio stuff: ********************************************* +**************************************************************************/ + + +typedef struct MSTREAM +{ struct MSTREAM *next; + CHAR *type; + CHAR *version; + BOOL (*Init)(void); + BOOL (*Test)(void); + BOOL (*Load)(void); + void (*Cleanup)(void); +} MSTREAM; + + +extern int stream_bufsize; +extern FILE *stream_fp; +extern SLONG stream_seekpos; +extern SLONG stream_reppos; + + +/************************************************************************** +****** Virtual channel stuff: ********************************************* +**************************************************************************/ + +extern BOOL VC_Init(void); +extern void VC_Exit(void); +extern BOOL VC_SetNumVoices(void); +extern ULONG VC_SampleSpace(int type); +extern ULONG VC_SampleLength(int type, SAMPLE *s); + +extern BOOL VC_PlayStart(void); +extern void VC_PlayStop(void); + +extern SWORD VC_SampleLoad(SAMPLOAD *sload, int type, FILE *fp); +extern void VC_SampleUnload(SWORD handle); + +extern void VC_WriteSamples(SBYTE *buf,ULONG todo); +extern ULONG VC_WriteBytes(SBYTE *buf,ULONG todo); +extern void VC_SilenceBytes(SBYTE *buf,ULONG todo); + +extern void VC_VoiceSetVolume(UBYTE voice, UWORD vol); +extern void VC_VoiceSetFrequency(UBYTE voice, ULONG frq); +extern void VC_VoiceSetPanning(UBYTE voice, ULONG pan); +extern void VC_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags); + +extern void VC_VoiceStop(UBYTE voice); +extern BOOL VC_VoiceStopped(UBYTE voice); +extern void VC_VoiceReleaseSustain(UBYTE voice); +extern SLONG VC_VoiceGetPosition(UBYTE voice); +extern ULONG VC_VoiceRealVolume(UBYTE voice); + + +extern BOOL VC2_Init(void); +extern void VC2_Exit(void); +extern BOOL VC2_SetNumVoices(void); +extern ULONG VC2_SampleSpace(int type); +extern ULONG VC2_SampleLength(int type, SAMPLE *s); + +extern BOOL VC2_PlayStart(void); +extern void VC2_PlayStop(void); + +extern SWORD VC2_SampleLoad(SAMPLOAD *sload, int type, FILE *fp); +extern void VC2_SampleUnload(SWORD handle); + +extern void VC2_WriteSamples(SBYTE *buf,ULONG todo); +extern ULONG VC2_WriteBytes(SBYTE *buf,ULONG todo); +extern void VC2_SilenceBytes(SBYTE *buf,ULONG todo); + +extern void VC2_VoiceSetVolume(UBYTE voice, UWORD vol); +extern void VC2_VoiceSetFrequency(UBYTE voice, ULONG frq); +extern void VC2_VoiceSetPanning(UBYTE voice, ULONG pan); +extern void VC2_VoicePlay(UBYTE voice,SWORD handle,ULONG start,ULONG size,ULONG reppos,ULONG repend,UWORD flags); + +extern void VC2_VoiceStop(UBYTE voice); +extern BOOL VC2_VoiceStopped(UBYTE voice); +extern void VC2_VoiceReleaseSustain(UBYTE voice); +extern SLONG VC2_VoiceGetPosition(UBYTE voice); + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/mmio.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,268 @@ +#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_SILENT 0 +#define LOG_VERBOSE 1 + +extern int log_init(CHAR *logfile, BOOL val); +extern void log_exit(void); +extern void log_verbose(void); +extern void log_silent(void); +extern void printlog(CHAR *fmt, ... ); +extern void printlogv(CHAR *fmt, ... ); + +#ifdef __WATCOMC__ +#pragma aux log_init parm nomemory modify nomemory; +#pragma aux log_exit parm nomemory modify nomemory; +#pragma aux log_verbose parm nomemory modify nomemory; +#pragma aux log_silent parm nomemory modify nomemory; +#pragma aux printlog parm nomemory modify nomemory; +#pragma aux printlogv parm nomemory modify nomemory; +#endif + + + +// MikMod's new error handling routines +// ==================================== + +// Specific Errors [referenced by _mm_errno] + +enum +{ MMERR_OPENING_FILE = 1, + MMERR_OUT_OF_MEMORY, + MMERR_END_OF_FILE, + MMERR_DISK_FULL, + MMERR_SAMPLE_TOO_BIG, + MMERR_OUT_OF_HANDLES, + MMERR_ALLOCATING_DMA, + MMERR_UNKNOWN_WAVE_TYPE, + MMERR_NOT_A_STREAM, + MMERR_LOADING_PATTERN, + MMERR_LOADING_TRACK, + MMERR_LOADING_HEADER, + MMERR_LOADING_SAMPLEINFO, + MMERR_NOT_A_MODULE, + MMERR_DETECTING_DEVICE, + MMERR_INVALID_DEVICE, + MMERR_INITIALIZING_MIXER, +#ifdef SUN +#elif defined(SOLARIS) +#elif defined(__alpha) + MMERR_AF_AUDIO_PORT +#elif defined(OSS) + #ifdef ULTRA + #endif +#elif defined(__hpux) + MMERR_OPENING_DEVAUDIO, + MMERR_SETTING_NONBLOCKING, + MMERR_SETTING_SAMPLEFORMAT, + MMERR_SETTING_SAMPLERATE, + MMERR_SETTING_CHANNELS, + MMERR_SELECTING_AUDIO_OUTPUT, + MMERR_GETTING_AUDIO_DESC, + MMERR_GETTING_GAINS, + MMERR_SETTING_GAINS, + MMERR_SETTING_BUFFERSIZE +#elif defined(AIX) + MMERR_OPENING_AIX, + MMERR_AIX_CONFIG_INIT, + MMERR_AIX_CONFIG_CONTROL, + MMERR_AIX_CONFIG_START, + MMERR_AIX_NON_BLOCK +#elif defined(SGI) +#elif defined(__OS2__) +#elif defined(__WIN32__) +#else + MMERR_DETECTING_SOUNDCARD, + MMERR_SETTING_HIDMA +#endif +}; + +// Memory allocation with error handling - MMALLOC.C +// ================================================= + +extern void *_mm_malloc(size_t size); +extern void *_mm_calloc(size_t nitems, size_t size); + +extern void (*_mm_errorhandler)(void); +extern int _mm_errno; +extern BOOL _mm_critical; +extern CHAR *_mm_errmsg[]; + +extern void _mm_RegisterErrorHandler(void (*proc)(void)); +extern BOOL _mm_FileExists(CHAR *fname); + +extern void StringWrite(CHAR *s, FILE *fp); +extern CHAR *StringRead(FILE *fp); + + +// 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) + + +extern int _mm_fseek(FILE *stream, long offset, int whence); +extern long _mm_iobase_get(void); +extern void _mm_iobase_set(long iobase); +extern void _mm_iobase_setcur(FILE *fp); +extern void _mm_iobase_revert(void); +extern long _mm_ftell(FILE *stream); +extern long _mm_flength(FILE *stream); +extern FILE *_mm_fopen(CHAR *fname, CHAR *attrib); +extern void _mm_fputs(FILE *fp, CHAR *data); +extern BOOL _mm_copyfile(FILE *fpi, FILE *fpo, ULONG len); +extern void _mm_write_string(CHAR *data, FILE *fp); +extern int _mm_read_string (CHAR *buffer, int number, FILE *fp); + + +//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_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); + +#ifdef __WATCOMC__ +#pragma aux _mm_fseek parm nomemory modify nomemory +#pragma aux _mm_ftell parm nomemory modify nomemory +#pragma aux _mm_flength parm nomemory modify nomemory +#pragma aux _mm_fopen parm nomemory modify nomemory +#pragma aux _mm_fputs parm nomemory modify nomemory +#pragma aux _mm_copyfile parm nomemory modify nomemory +#pragma aux _mm_iobase_get parm nomemory modify nomemory +#pragma aux _mm_iobase_set parm nomemory modify nomemory +#pragma aux _mm_iobase_setcur parm nomemory modify nomemory +#pragma aux _mm_iobase_revert parm nomemory modify nomemory +#pragma aux _mm_write_string parm nomemory modify nomemory +#pragma aux _mm_read_string parm nomemory modify nomemory + +#pragma aux _mm_read_M_SWORD parm nomemory modify nomemory; +#pragma aux _mm_read_I_SWORD parm nomemory modify nomemory; +#pragma aux _mm_read_M_UWORD parm nomemory modify nomemory; +#pragma aux _mm_read_I_UWORD parm nomemory modify nomemory; +#pragma aux _mm_read_M_SLONG parm nomemory modify nomemory; +#pragma aux _mm_read_I_SLONG parm nomemory modify nomemory; +#pragma aux _mm_read_M_ULONG parm nomemory modify nomemory; +#pragma aux _mm_read_I_ULONG parm nomemory modify nomemory; + +#pragma aux _mm_read_M_SWORDS parm nomemory modify nomemory; +#pragma aux _mm_read_I_SWORDS parm nomemory modify nomemory; +#pragma aux _mm_read_M_UWORDS parm nomemory modify nomemory; +#pragma aux _mm_read_I_UWORDS parm nomemory modify nomemory; +#pragma aux _mm_read_M_SLONGS parm nomemory modify nomemory; +#pragma aux _mm_read_I_SLONGS parm nomemory modify nomemory; +#pragma aux _mm_read_M_ULONGS parm nomemory modify nomemory; +#pragma aux _mm_read_I_ULONGS parm nomemory modify nomemory; + +#pragma aux _mm_write_M_SWORD parm nomemory modify nomemory; +#pragma aux _mm_write_I_SWORD parm nomemory modify nomemory; +#pragma aux _mm_write_M_UWORD parm nomemory modify nomemory; +#pragma aux _mm_write_I_UWORD parm nomemory modify nomemory; +#pragma aux _mm_write_M_SLONG parm nomemory modify nomemory; +#pragma aux _mm_write_I_SLONG parm nomemory modify nomemory; +#pragma aux _mm_write_M_ULONG parm nomemory modify nomemory; +#pragma aux _mm_write_I_ULONG parm nomemory modify nomemory; + +#pragma aux _mm_write_M_SWORDS parm nomemory modify nomemory; +#pragma aux _mm_write_I_SWORDS parm nomemory modify nomemory; +#pragma aux _mm_write_M_UWORDS parm nomemory modify nomemory; +#pragma aux _mm_write_I_UWORDS parm nomemory modify nomemory; +#pragma aux _mm_write_M_SLONGS parm nomemory modify nomemory; +#pragma aux _mm_write_I_SLONGS parm nomemory modify nomemory; +#pragma aux _mm_write_M_ULONGS parm nomemory modify nomemory; +#pragma aux _mm_write_I_ULONGS parm nomemory modify nomemory; +#endif + + +#ifndef __WATCOMC__ +#ifndef __GNUC__ +extern CHAR *strdup(CHAR *str); +#endif +#endif + +#ifdef __cplusplus +}; +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/ptform.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,591 @@ +/* + --> The Protracker Enums + -> For MikMod 3.0 +*/ + +#ifndef _PTFORM_H_ +#define _PTFORM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +extern UWORD mytab[12],logtab[104]; +extern UBYTE VibratoTable[32],avibtab[128]; +extern SBYTE PanbrelloTable[256]; +extern ULONG lintab[768]; + + +/************************************************************************** +****** Unitrack stuff: **************************************************** +**************************************************************************/ + +// The UniTrack stuff is generally for internal use only, but would be +// required in making a tracker or a module player tha scrolls pattern +// data. + +// prototypes: + +extern void UniSetRow(UBYTE *t); +extern UBYTE UniGetByte(void); +extern UBYTE *UniFindRow(UBYTE *t,UWORD row); +extern void UniReset(void); +extern void UniWrite(UBYTE data); +extern void UniNewline(void); +extern UBYTE *UniDup(void); +extern void UniSkipOpcode(UBYTE op); +extern BOOL UniInit(void); +extern void UniCleanup(void); +extern UWORD TrkLen(UBYTE *t); +extern BOOL MyCmp(UBYTE *a, UBYTE *b, UWORD l); +extern void UniInstrument(UBYTE ins); +extern void UniNote(UBYTE note); +extern void UniPTEffect(UBYTE eff, UBYTE dat); +extern void UniVolEffect(UWORD eff, UBYTE dat); + + +// Enumaerated UniMod Commands + +enum +{ UNI_NOTE = 1, + UNI_INSTRUMENT, + UNI_PTEFFECT0, + UNI_PTEFFECT1, + UNI_PTEFFECT2, + UNI_PTEFFECT3, + UNI_PTEFFECT4, + UNI_PTEFFECT5, + UNI_PTEFFECT6, + UNI_PTEFFECT7, + UNI_PTEFFECT8, + UNI_PTEFFECT9, + UNI_PTEFFECTA, + UNI_PTEFFECTB, + UNI_PTEFFECTC, + UNI_PTEFFECTD, + UNI_PTEFFECTE, + UNI_PTEFFECTF, + UNI_S3MEFFECTA, + UNI_S3MEFFECTD, + UNI_S3MEFFECTE, + UNI_S3MEFFECTF, + UNI_S3MEFFECTI, + UNI_S3MEFFECTQ, + UNI_S3MEFFECTR, + UNI_S3MEFFECTT, + UNI_S3MEFFECTU, + UNI_KEYOFF, + UNI_KEYFADE, + UNI_VOLEFFECTS, + UNI_XMEFFECT4, + UNI_XMEFFECTA, + UNI_XMEFFECTE1, + UNI_XMEFFECTE2, + UNI_XMEFFECTEA, + UNI_XMEFFECTEB, + UNI_XMEFFECTG, + UNI_XMEFFECTH, + UNI_XMEFFECTL, + UNI_XMEFFECTP, + UNI_XMEFFECTX1, + UNI_XMEFFECTX2, + UNI_ITEFFECTG, // Porta to Note .. no kick=0; + UNI_ITEFFECTH, // IT specific Vibrato + UNI_ITEFFECTI, // IT tremor (xy not incremeneted) + UNI_ITEFFECTM, // Set Channel Volume + UNI_ITEFFECTN, // Slide / Fineslide Channel Volume + UNI_ITEFFECTP, // Slide / Fineslide Channel Panning + UNI_ITEFFECTU, // IT fine vibrato + UNI_ITEFFECTW, // Slide / Fineslide Global volume + UNI_ITEFFECTY, // The Satanic Panbrello + UNI_ITEFFECTS0, + UNI_LAST +}; + + +// IT / S3M Extended SS effects: + +enum +{ SS_GLISSANDO = 1, + SS_FINETUNE, + SS_VIBWAVE, + SS_TREMWAVE, + SS_PANWAVE, + SS_FRAMEDELAY, + SS_S7EFFECTS, + SS_PANNING, + SS_SURROUND, + SS_HIOFFSET, + SS_PATLOOP, + SS_NOTECUT, + SS_NOTEDELAY, + SS_PATDELAY +}; + + +// IT Volume column effects + +enum +{ VOL_VOLUME = 1, + VOL_PANNING, + VOL_VOLSLIDE, + VOL_PITCHSLIDEDN, + VOL_PITCHSLIDEUP, + VOL_PORTAMENTO, + VOL_VIBRATO +}; + + +/************************************************************************** +****** Instrument stuff: ************************************************** +**************************************************************************/ + + +// Instrument format flags +#define IF_OWNPAN 1 +#define IF_PITCHPAN 2 + +// Envelope flags: + +#define EF_ON 1 +#define EF_SUSTAIN 2 +#define EF_LOOP 4 +#define EF_VOLENV 8 + +// New Note Action Flags + +#define NNA_CUT 0 +#define NNA_CONTINUE 1 +#define NNA_OFF 2 +#define NNA_FADE 3 + +#define DCT_OFF 0 +#define DCT_NOTE 1 +#define DCT_SAMPLE 2 +#define DCT_INST 3 + +#define DCA_CUT 0 +#define DCA_OFF 1 +#define DCA_FADE 2 + +#define KEY_KICK 0 +#define KEY_OFF 1 +#define KEY_FADE 2 +#define KEY_KILL 3 + +#define AV_IT 1 // IT vs. XM vibrato info + + +typedef struct ENVPT +{ SWORD pos; + SWORD val; +} ENVPT; + + +typedef struct INSTRUMENT +{ + UBYTE flags; + + UBYTE samplenumber[120]; + UBYTE samplenote[120]; + + UBYTE nnatype; + UBYTE dca; // duplicate check action + UBYTE dct; // duplicate check type + UBYTE globvol; + UWORD panning; // instrument-based panning var + + UBYTE pitpansep; // pitch pan separation (0 to 255) + UBYTE pitpancenter; // pitch pan center (0 to 119) + UBYTE rvolvar; // random volume varations (0 - 100%) + UBYTE rpanvar; // random panning varations (0 - 100%) + + UWORD volfade; + + UBYTE volflg; // bit 0: on 1: sustain 2: loop + UBYTE volpts; + UBYTE volsusbeg; + UBYTE volsusend; + UBYTE volbeg; + UBYTE volend; + ENVPT volenv[32]; + + UBYTE panflg; // bit 0: on 1: sustain 2: loop + UBYTE panpts; + UBYTE pansusbeg; + UBYTE pansusend; + UBYTE panbeg; + UBYTE panend; + ENVPT panenv[32]; + + UBYTE pitflg; // bit 0: on 1: sustain 2: loop + UBYTE pitpts; + UBYTE pitsusbeg; + UBYTE pitsusend; + UBYTE pitbeg; + UBYTE pitend; + ENVPT pitenv[32]; + +// UBYTE vibtype; +// UBYTE vibsweep; +// UBYTE vibdepth; +// UBYTE vibrate; + + CHAR *insname; + +} INSTRUMENT; + + + +/************************************************************************** +****** Player stuff: ****************************************************** +**************************************************************************/ + +typedef struct ENVPR +{ UBYTE flg; // envelope flag + UBYTE pts; // number of envelope points + UBYTE susbeg; // envelope sustain index begin + UBYTE susend; // envelope sustain index end + UBYTE beg; // envelope loop begin + UBYTE end; // envelope loop end + SWORD p; // current envelope counter + UWORD a; // envelope index a + UWORD b; // envelope index b + ENVPT *env; // envelope points +} ENVPR; + + + +// Struct MP_VOICE - Used by NNA only player (audio control. AUDTMP is +// used for full effects control). +typedef struct MP_VOICE +{ INSTRUMENT *i; + SAMPLE *s; + UBYTE sample; // which instrument number + + SWORD volume; // output volume (vol + sampcol + instvol) + UWORD panning; // panning position + SBYTE chanvol; // channel's "global" volume + UWORD fadevol; // fading volume rate + UWORD period; // period to play the sample at + + UBYTE volflg; // volume envelope settings + UBYTE panflg; // panning envelope settings + UBYTE pitflg; // pitch envelope settings + + UBYTE keyoff; // if true = fade out and stuff + UBYTE kick; // if true = sample has to be restarted + UBYTE note; // the audible note (as heard, direct rep of period) + UBYTE nna; // New note action type + master/slave flags + SWORD handle; // which sample-handle + SLONG start; // The start byte index in the sample + + + // ---------------------------------- + // Below here is info NOT in MP_CONTROL!! + // ---------------------------------- + + ENVPR venv; + ENVPR penv; + ENVPR cenv; + + UWORD avibpos; // autovibrato pos + UWORD aswppos; // autovibrato sweep pos + + ULONG totalvol; // total volume of channel (before global mixings) + + BOOL mflag; + SWORD masterchn; + struct MP_CONTROL *master;// index of "master" effects channel +} MP_VOICE; + + +typedef struct MP_CONTROL +{ INSTRUMENT *i; + SAMPLE *s; + UBYTE sample; // which sample number + UBYTE note; // the audible note (as heard, direct rep of period) + SWORD outvolume; // output volume (vol + sampcol + instvol) + SBYTE chanvol; // channel's "global" volume + UWORD fadevol; // fading volume rate + UWORD panning; // panning position + UBYTE kick; // if true = sample has to be restarted + UBYTE muted; // if set, channel not played + UWORD period; // period to play the sample at + UBYTE nna; // New note action type + master/slave flags + + UBYTE volflg; // volume envelope settings + UBYTE panflg; // panning envelope settings + UBYTE pitflg; // pitch envelope settings + + UBYTE keyoff; // if true = fade out and stuff + SWORD handle; // which sample-handle + UBYTE notedelay; // (used for note delay) + SLONG start; // The starting byte index in the sample + + struct MP_VOICE *slave;// Audio Slave of current effects control channel + UBYTE slavechn; // Audio Slave of current effects control channel + UBYTE anote; // the note that indexes the audible (note seen in tracker) + SWORD ownper; + SWORD ownvol; + UBYTE dca; // duplicate check action + UBYTE dct; // duplicate check type + UBYTE *row; // row currently playing on this channel + SBYTE retrig; // retrig value (0 means don't retrig) + ULONG speed; // what finetune to use + SWORD volume; // amiga volume (0 t/m 64) to play the sample at + + SBYTE tmpvolume; // tmp volume + UWORD tmpperiod; // tmp period + UWORD wantedperiod; // period to slide to (with effect 3 or 5) + UBYTE pansspd; // panslide speed + UWORD slidespeed; // + UWORD portspeed; // noteslide speed (toneportamento) + + UBYTE s3mtremor; // s3m tremor (effect I) counter + UBYTE s3mtronof; // s3m tremor ontime/offtime + UBYTE s3mvolslide; // last used volslide + UBYTE s3mrtgspeed; // last used retrig speed + UBYTE s3mrtgslide; // last used retrig slide + + UBYTE glissando; // glissando (0 means off) + UBYTE wavecontrol; // + + SBYTE vibpos; // current vibrato position + UBYTE vibspd; // "" speed + UBYTE vibdepth; // "" depth + + SBYTE trmpos; // current tremolo position + UBYTE trmspd; // "" speed + UBYTE trmdepth; // "" depth + + UBYTE fslideupspd; + UBYTE fslidednspd; + UBYTE fportupspd; // fx E1 (extra fine portamento up) data + UBYTE fportdnspd; // fx E2 (extra fine portamento dn) data + UBYTE ffportupspd; // fx X1 (extra fine portamento up) data + UBYTE ffportdnspd; // fx X2 (extra fine portamento dn) data + + ULONG hioffset; // last used high order of sample offset + UWORD soffset; // last used low order of sample-offset (effect 9) + + UBYTE sseffect; // last used Sxx effect + UBYTE ssdata; // last used Sxx data info + UBYTE chanvolslide; // last used channel volume slide + + UBYTE panbwave; // current panbrello waveform + UBYTE panbpos; // current panbrello position + SBYTE panbspd; // "" speed + UBYTE panbdepth; // "" depth + + UWORD newsamp; // set to 1 upon a sample / inst change + UBYTE voleffect; // Volume Column Effect Memory as used by Impulse Tracker + UBYTE voldata; // Volume Column Data Memory +} MP_CONTROL; + + +/****************************************************** +******** MikMod UniMod type: ************************** +*******************************************************/ + +// UniMod flags +#define UF_XMPERIODS 1 // XM periods / finetuning +#define UF_LINEAR 2 // LINEAR periods (UF_XMPERIODS must be set as well) +#define UF_INST 4 // Instruments are used +#define UF_NNA 8 // New Note Actions used (set numvoices rather than numchn) + + +typedef struct UNIMOD +{ + // This section of elements are all file-storage related. + // all of this information can be found in the UNIMOD disk format. + // For further details about there variables, see the MikMod Docs. + + UWORD flags; // See UniMod Flags above + UBYTE numchn; // number of module channels + UBYTE numvoices; // max # voices used for full NNA playback + UWORD numpos; // number of positions in this song + UWORD numpat; // number of patterns in this song + UWORD numtrk; // number of tracks + UWORD numins; // number of instruments + UWORD numsmp; // number of samples + UWORD reppos; // restart position + UBYTE initspeed; // initial song speed + UBYTE inittempo; // initial song tempo + UBYTE initvolume; // initial global volume (0 - 128) + UWORD panning[64]; // 64 panning positions + UBYTE chanvol[64]; // 64 channel positions + CHAR *songname; // name of the song + CHAR *composer; // name of the composer + CHAR *comment; // module comments + UBYTE **tracks; // array of numtrk pointers to tracks + UWORD *patterns; // array of Patterns [pointers to tracks for each channel]. + UWORD *pattrows; // array of number of rows for each pattern + UWORD *positions; // all positions + INSTRUMENT *instruments; // all instruments + SAMPLE *samples; // all samples + + // following are the player-instance variables. They are in no way file + // storage related - they are for internal replay use only. + + // All following variables can be modified at any time. + + CHAR *modtype; // string type of module loaded + UBYTE bpm; // current beats-per-minute speed + UWORD sngspd; // current song speed + SWORD volume; // song volume (0-128) (or user volume) + BOOL extspd; // extended speed flag (default enabled) + BOOL panflag; // panning flag (default enabled) + BOOL loop; // loop module ? (default disabled) + BOOL forbid; // if true, no player update! + + // The following variables are considered useful for reading, and should + // should not be directly modified by the end user. + + MP_CONTROL *control; // Effects Channel information (pf->numchn alloc'ed) + MP_VOICE *voice; // Audio Voice information (md_numchn alloc'ed) + UWORD numrow; // number of rows on current pattern + UWORD vbtick; // tick counter (counts from 0 to sngspd) + UWORD patpos; // current row number + SWORD sngpos; // current song position. This should not + // be modified directly. Use MikMod_NextPosition, + // MikMod_PrevPosition, and MikMod_SetPosition. + + // The following variables should not be modified, and have information + // that is pretty useless outside the internal player, so just ignore :) + + UBYTE globalslide; // global volume slide rate + UWORD pat_reppos; // patternloop position + UWORD pat_repcnt; // times to loop + UWORD patbrk; // position where to start a new pattern + UBYTE patdly; // patterndelay counter (command memory) + UBYTE patdly2; // patterndelay counter (real one) + SWORD posjmp; // flag to indicate a position jump is needed... + // changed since 1.00: now also indicates the + // direction the position has to jump to: + // 0: Don't do anything + // 1: Jump back 1 position + // 2: Restart on current position + // 3: Jump forward 1 position + +} UNIMOD; + + +/*************************************************** +****** Loader stuff: ******************************* +****************************************************/ + +// loader structure: + +typedef struct MLOADER +{ struct MLOADER *next; + CHAR *type; + CHAR *version; + BOOL (*Init)(void); + BOOL (*Test)(void); + BOOL (*Load)(void); + void (*Cleanup)(void); + CHAR *(*LoadTitle)(void); +} MLOADER; + +// public loader variables: + +extern FILE *modfp; +extern UWORD finetune[16]; +extern UNIMOD of; // static unimod loading space +extern UWORD npertab[60]; // used by the original MOD loaders + +// main loader prototypes: + +void ML_InfoLoader(void); +void ML_RegisterLoader(MLOADER *ldr); +UNIMOD *MikMod_LoadSongFP(FILE *fp, int maxchan); +UNIMOD *MikMod_LoadSong(CHAR *filename, int maxchan); +void MikMod_FreeSong(UNIMOD *mf); + + +// other loader prototypes: (used by the loader modules) + +BOOL InitTracks(void); +void AddTrack(UBYTE *tr); +BOOL ReadComment(UWORD len); +BOOL AllocPositions(int total); +BOOL AllocPatterns(void); +BOOL AllocTracks(void); +BOOL AllocInstruments(void); +BOOL AllocSamples(void); +CHAR *DupStr(CHAR *s, UWORD len); + + +// Declare external loaders: + +extern MLOADER load_uni; // Internal UniMod Loader (Current version of UniMod only) +extern MLOADER load_mod; // Standard 31-instrument Module loader (Protracker, StarTracker, FastTracker, etc) +extern MLOADER load_m15; // 15-instrument (SoundTracker and Ultimate SoundTracker) +extern MLOADER load_mtm; // Multi-Tracker Module (by Renaissance) +extern MLOADER load_s3m; // ScreamTracker 3 (by Future Crew) +extern MLOADER load_stm; // ScreamTracker 2 (by Future Crew) +extern MLOADER load_ult; // UltraTracker +extern MLOADER load_xm; // FastTracker 2 (by Trition) +extern MLOADER load_it; // Impulse Tracker (by Jeffrey Lim) +extern MLOADER load_669; // 669 and Extended-669 (by Tran / Renaissance) +extern MLOADER load_dsm; // DSIK internal module format +extern MLOADER load_med; // MMD0 and MMD1 Amiga MED modules (by OctaMED) +extern MLOADER load_far; // Farandole Composer Module + +// used to convert c4spd to linear XM periods (IT loader). +extern UWORD getlinearperiod(UBYTE note, ULONG fine); +extern ULONG getfrequency(UBYTE flags, ULONG period); + + +#define MP_HandleTick Player_HandleTick +#define ML_LoadFN(x,y) MikMod_LoadSong(x,y) +#define ML_LoadFP(x,y) MikMod_LoadSongFP(x,y) +#define MP_PlayStart(x) Player_Start(x) +#define MP_PlayStop Player_Stop + + +// MikMod Player Prototypes: +// =========================================================== +// This batch of prototypes affects the currently ACTIVE module +// set with MikMod_PlayStart) + +extern void Player_Start(UNIMOD *mf); +extern BOOL Player_Active(void); +extern void Player_Stop(void); +extern void Player_TogglePause(void); +extern void Player_NextPosition(void); +extern void Player_PrevPosition(void); +extern void Player_SetPosition(UWORD pos); +extern void Player_Mute(SLONG arg1, ...); +extern void Player_UnMute(SLONG arg1, ...); +extern void Player_ToggleMute(SLONG arg1, ...); +extern BOOL Player_Muted(int chan); +extern void Player_HandleTick(void); +extern void Player_SetVolume(int volume); +extern UNIMOD *Player_GetUnimod(void); + +extern BOOL Player_Init(UNIMOD *mf); // internal use only [by loader] +extern void Player_Exit(UNIMOD *mf); // internal use only [by loader] + +// This batch of prototypes adheres closely to the old MikMod 2.10 +// naming, and affects ANY specified module (need not be active, +// only loaded and initialized) + +extern BOOL MP_Playing(UNIMOD *mf); +extern void MP_TogglePause(UNIMOD *mf); +extern void MP_NextPosition(UNIMOD *mf); +extern void MP_PrevPosition(UNIMOD *mf); +extern void MP_SetPosition(UNIMOD *mf, UWORD pos); +extern void MP_Mute(UNIMOD *mf, SLONG arg1, ...); +extern void MP_UnMute(UNIMOD *mf, SLONG arg1, ...); +extern void MP_ToggleMute(UNIMOD *mf, SLONG arg1, ...); +extern BOOL MP_Muted(UNIMOD *mf, int chan); + +#ifdef __cplusplus +} +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/tdefs.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,105 @@ +/* + TDEFS.H : Type definitions for the more commonly used type statements. + A 'shortened' version of MTYPES.H that has only what I use most. + + This module is my hidden secret of "portability" to many compilers + and platforms. I really love C sometimes.. ;) +*/ + + +#ifndef TDEFS_H +#define TDEFS_H + + +/* + MikMod atomic types: + ==================== +*/ + +typedef char CHAR; + +#ifdef __OS2__ + +typedef signed char SBYTE; /* has to be 1 byte signed */ +typedef unsigned char UBYTE; /* has to be 1 byte unsigned */ +typedef signed short SWORD; /* has to be 2 bytes signed */ +typedef unsigned short UWORD; /* has to be 2 bytes unsigned */ +typedef signed long SLONG; /* has to be 4 bytes signed */ +/* ULONG and BOOL are already defined in OS2.H */ + +#elif defined(__alpha) + +typedef signed char SBYTE; /* has to be 1 byte signed */ +typedef unsigned char UBYTE; /* has to be 1 byte unsigned */ +typedef signed short SWORD; /* has to be 2 bytes signed */ +typedef unsigned short UWORD; /* has to be 2 bytes unsigned */ +/* long is 8 bytes on dec alpha - RCA */ +typedef signed int SLONG; /* has to be 4 bytes signed */ +typedef unsigned int ULONG; /* has to be 4 bytes unsigned */ +typedef int BOOL; /* doesn't matter.. 0=FALSE, <>0 true */ + +#else + +typedef signed char SBYTE; /* has to be 1 byte signed */ +typedef unsigned char UBYTE; /* has to be 1 byte unsigned */ +typedef signed short SWORD; /* has to be 2 bytes signed */ +typedef unsigned short UWORD; /* has to be 2 bytes unsigned */ +typedef signed long SLONG; /* has to be 4 bytes signed */ +typedef unsigned long ULONG; /* has to be 4 bytes unsigned */ +typedef int BOOL; /* doesn't matter.. 0=FALSE, <>0 true */ + +#endif + + +#ifdef __OS2__ +#define INCL_DOS +#define INCL_MCIOS2 +#define INCL_MMIOOS2 +#include <os2.h> +#include <os2me.h> +#include <mmio.h> +#endif + + +#ifdef __WATCOMC__ + +typedef __int64 SDOUBLE; +typedef unsigned __int64 UDOUBLE; + +#define inportb(x) inp(x) +#define outportb(x,y) outp(x,y) +#define inport(x) inpw(x) +#define outport(x,y) outpw(x,y) +#define disable() _disable() +#define enable() _enable() +#endif + +#ifdef __BORLANDC__ +#define inp(x) inportb(x) +#define outp(x,y) outportb(x,y) +#define inpw(x) inport(x) +#define outpw(x,y) outport(x,y) +#define _disable() disable() +#define _enable() enable() +#endif + +#ifdef __DJGPP__ +#include <dpmi.h> +#include <go32.h> +#include <pc.h> +#define inp inportw +#define outport outportw +#define inport inportw +#define interrupt +#endif + +#if defined(__OS2__) + #define delay(x) DosSleep(x); +#elif defined(__WIN32__) + #define delay(x) Sleep(x); +#elif defined(__GNUC__) + #define delay(x) ; +#endif + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/timer.h Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,88 @@ +/* + FILE : TIMER.H + + DOS-based Timer Interrupt functions + Includes defines for TIMER.C and VTIMER.C +*/ + +#ifndef VTIMER_H +#define VTIMER_H + +#include "tdefs.h" + +#define VT_VRSYNC 1 +#define VT_CALLOLD 2 + +#ifdef __cplusplus +extern "C" { +#endif + +// Defined in TIMER.C + +void Timer_Exit(void); +void Timer_Init(int rate, void (*handler)(void)); +void Timer_SetSpeed(UWORD rate); +void Timer_Start(void); +void Timer_Stop(void); + + +// Defined in VTIMER.C +void VT_Exit(void); +void VT_Init(void); +SWORD VT_Alloc(void); +void VT_Free(SWORD handle); +void VT_SetHandler(SWORD handle,void (*handler)(void)); +void VT_SetSpeed(SWORD handle,SLONG speed); +void VT_SetBPM(SWORD handle,UBYTE bpm); +void VT_Start(SWORD handle); +void VT_Stop(SWORD handle); +void VT_Mode(UBYTE flags); +void VT_V0Handler(void (*handler)(void)); +void VT_V1Handler(void (*handler)(void)); + +#ifdef __cplusplus +} +#endif + + +extern volatile int framecount; +void framecounter(void); + +// COUNTER.C defnitions +// (ObjectGraphics Library) + +#define CNT_ACTIVE 16 +#define CNT_VALUE 0 +#define CNT_POINTER 1 +#define CNT_FUNCTION 2 +#define CNT_TYPE 15 + +typedef struct COUNTER +{ struct COUNTER *next, *prev; + UBYTE flags; + ULONG counter; + ULONG resetcount; + int increment; + int value; + int stopvalue; +} COUNTER; + + +// Defined in COUNTER.C +// (ObjectGraphics Library) + +COUNTER *RegisterCounter(ULONG initcount, ULONG resetcount, int value, int increment, int stopvalue, UBYTE flags); +void RemoveCounter(COUNTER *counter); +void StartCounter(COUNTER *counter); +void StopCounter(COUNTER *counter); + +#ifdef DJGPP +#include <dpmi.h> +typedef void (*PVI)(); +#define interrupt +#define far +void _dos_setvect(unsigned vector, PVI handler); +PVI _dos_getvect(unsigned vector); +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmio/mmalloc.c Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,59 @@ +/* + --> The MMIO Portable Memory Management functions + -> Divine Entertainment GameDev Libraries + + Copyright © 1997 by Jake Stine and Divine Entertainment + +*/ + +#include "mmio.h" + + +// Same as malloc, but sets error variable _mm_error when it failed +void *_mm_malloc(size_t size) +{ + void *d; + + if((d=malloc(size))==NULL) + { _mm_errno = MMERR_OUT_OF_MEMORY; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + } + + return d; +} + + +// Same as calloc, but sets error variable _mm_error when it failed +void *_mm_calloc(size_t nitems, size_t size) +{ + void *d; + + if((d=calloc(nitems,size))==NULL) + { _mm_errno = MMERR_OUT_OF_MEMORY; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + } + + return d; +} + + +#ifndef __WATCOMC__ +#ifndef __GNUC__ +// Same as Watcom's strdup function - allocates memory for a string +// and makes a copy of it. Ruturns NULL if failed. +CHAR *strdup(CHAR *src) +{ + CHAR *buf; + + if((buf = (CHAR *)_mm_malloc(strlen(src)+1)) == NULL) + { _mm_errno = MMERR_OUT_OF_MEMORY; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + return NULL; + } + + strcpy(buf,src); + return buf; +} +#endif +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmio/mmerror.c Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,103 @@ +/* + --> The MM_Error Portable Error Handling Functions + -> Divine Entertainment GameDev Libraries + + File: MMERROR.C + + Description: + Error handling functions for use with the DivEnt MMIO and MikMod + libraries. Register an error handler with _mm_RegisterErrorHandler() + and you're all set. + + NOTES: + + - the global variables _mm_error, _mm_errno, and _mm_critical are + set before the error handler in called. See below for the values + of these variables. + +-------------------------- + + +*/ + + +#include "mmio.h" + +CHAR *_mm_errmsg[] = +{ + "", + +// Generic MikMod Errors [referenced by _mm_error] +// ----------------------------------------------- + + "Cannot open requested file", + "Out of memory", + "Unexpected end of file", + "Cannot write to file - Disk full", + +// Specific Misceallenous Errors: + + "Sample load failed - Out of memory", + "Sample load failed - Out of sample handles", + "Could not allocate page-contiguous dma-buffer", + "Unknown wave file or sample type", + "Unknown streaming audio type", + +// Specific Module Loader [MLOADER.C] errors: + + "Failure loading module pattern", + "Failure loading module track", + "Failure loading module header", + "Failure loading sampleinfo", + "Unknown module format", + +// Specific Driver [MDRIVER.C / drivers] errors: + + "None of the supported sound-devices were detected", + "Device number out of range", + "Software mixer failure - Out of memory", + +#ifdef SUN +#elif defined(SOLARIS) +#elif defined(__alpha) + "Cannot find suitable audio port!" +#elif defined(OSS) + #ifdef ULTRA + #endif +#elif defined(__hpux) + "Unable to open /dev/audio", + "Unable to set non-blocking mode for /dev/audio", + "Unable to select 16bit-linear sample format", + "Could not select requested sample-rate", + "Could not select requested number of channels", + "Unable to select audio output", + "Unable to get audio description", + "Unable to get gain values", + "Unable to set gain values", + "Could not set transmission buffer size" +#elif defined(AIX) + "Could not open AIX audio device", + "Configuration (init) of AIX audio device failed", + "Configuration (control) of AIX audio device failed", + "Configuration (start) of AIX audio device failed", + "Unable to set non-blocking mode for /dev/audio", +#elif defined(SGI) +#elif defined(__OS2__) +#elif defined(__WIN32__) +#else + "The requested soundcard was not found", + "Could not open a High-DMA channel" +#endif +}; + + +void (*_mm_errorhandler)(void) = NULL; +int _mm_errno = 0; +BOOL _mm_critical = 0; + + +void _mm_RegisterErrorHandler(void (*proc)(void)) +{ + _mm_errorhandler = proc; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmio/mmio.c Fri Jan 23 16:05:11 1998 +0000 @@ -0,0 +1,455 @@ +/* + --> The MMIO Portable Input/Output functions + -> Divine Entertainment GameDev Libraries + + File: MMIO.C + + Description: + Miscellaneous I/O routines.. used to solve some portability issues + (like big/little endian machines and word alignment in structures ) + Also includes mikmod's ingenious error handling variable. + + Portability: + All systems - all compilers + + + ----------------------------------- + The way this module works - By Jake Stine [Air Richter] + + - _mm_fopen and _mm_copyfile will call the errorhandler [see mmerror.c] in + addition to setting _mm_errno on exit. + + - _mm_iobase is for internal use. It is used by ML_LoadFP() to ensure that it + works properly with wad files. + + - _mm_read_I_UWORD and _mm_read_M_UWORD have distinct differences: + the first is for reading data written by a little endian (intel) machine, + and the second is for reading big endian (Mac, RISC, Alpha) machine data. + + - _mm_write functions work the same as the _mm_read functions. + + - _mm_read_string is for reading binary strings. It is basically the same + as an fread of bytes. +*/ + +#include "mmio.h" +#include <string.h> + +#define COPY_BUFSIZE 1024 + +static long _mm_iobase = 0, + temp_iobase = 0; + +UBYTE _mm_cpybuf[COPY_BUFSIZE]; + + +void StringWrite(CHAR *s, FILE *fp) +// Specialized file output procedure. Writes a UWORD length and then a +// string of the specified length (no NULL terminator) afterward. +{ + int slen; + + if(s==NULL) + { _mm_write_I_UWORD(0,fp); + } else + { _mm_write_I_UWORD(slen = strlen(s),fp); + _mm_write_UBYTES(s,slen,fp); + } +} + +CHAR *StringRead(FILE *fp) +// Reads strings written out by StringWrite above: a UWORD length followed +// by length characters. A NULL is added to the string after loading. +{ + CHAR *s; + UWORD len; + + len = _mm_read_I_UWORD(fp); + if(len==0) + { s = _mm_calloc(16, sizeof(CHAR)); + } else + { if((s = (CHAR *)_mm_malloc(len+1)) == NULL) return NULL; + _mm_read_UBYTES(s,len,fp); + s[len] = 0; + } + + return s; +} + + +FILE *_mm_fopen(CHAR *fname, CHAR *attrib) +{ + FILE *fp; + + if((fp=fopen(fname,attrib)) == NULL) + { _mm_errno = _mm_errno = MMERR_OPENING_FILE; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + } + return fp; +} + + +int _mm_fseek(FILE *stream, long offset, int whence) +{ + return fseek(stream,(whence==SEEK_SET) ? offset+_mm_iobase : offset, whence); +} + + +long _mm_ftell(FILE *stream) +{ + return ftell(stream)-_mm_iobase; +} + + +BOOL _mm_FileExists(CHAR *fname) +{ + FILE *fp; + + if((fp=fopen(fname,"r")) == NULL) return 0; + fclose(fp); + + return 1; +} + + +long _mm_flength(FILE *stream) +{ + long tmp,tmp2; + + tmp = ftell(stream); + fseek(stream,0,SEEK_END); + tmp2 = ftell(stream); + fseek(stream,tmp,SEEK_SET); + return tmp2-tmp; +} + + +long _mm_iobase_get(void) +{ + return _mm_iobase; +} + + +void _mm_iobase_set(long iobase) +{ + temp_iobase = _mm_iobase; // store old value in case of revert + _mm_iobase = iobase; +} + + +// Sets the current file-position as the new _mm_iobase +void _mm_iobase_setcur(FILE *fp) +{ + temp_iobase = _mm_iobase; // store old value in case of revert + _mm_iobase = ftell(fp); +} + + +// Reverts to the last known _mm_iobase value. +void _mm_iobase_revert(void) +{ + _mm_iobase = temp_iobase; +} + + +// Procedure: _mm_copyfile +// Copies a given number of bytes from the source file to the destination +// file. Returns 1 on error, and calls the _mm_errnohandler, if registered. +BOOL _mm_copyfile(FILE *fpi, FILE *fpo, ULONG len) +{ + ULONG todo; + + while(len) + { todo = (len > COPY_BUFSIZE) ? COPY_BUFSIZE : len; + if(!fread(_mm_cpybuf, todo, 1, fpi)) + { _mm_errno = _mm_errno = MMERR_END_OF_FILE; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + return 1; + } + if(!fwrite(_mm_cpybuf, todo, 1, fpo)) + { _mm_errno = _mm_errno = MMERR_DISK_FULL; + if(_mm_errorhandler!=NULL) _mm_errorhandler(); + return 1; + } + len -= todo; + } + + return 0; +} + + +void _mm_write_string(CHAR *data, FILE *fp) +{ + if(data!=NULL) + _mm_write_UBYTES(data, strlen(data), fp); +} + + +void _mm_fputs(FILE *fp, CHAR *data) +{ + if(data != NULL) + _mm_write_UBYTES(data, strlen(data), fp); + +#ifndef __UNIX__ + _mm_write_UBYTE(13,fp); +#endif + _mm_write_UBYTE(10,fp); +} + + + +/************* +// These have accompanying #define's in mmio.h + +void _mm_write_SBYTE(SBYTE data, FILE *fp) +{ + fputc(data,fp); +} + +void _mm_write_UBYTE(UBYTE data,FILE *fp) +{ + fputc(data,fp); +} +*/ + +#ifdef MM_BIG_ENDIAN + +// --> Big Endian Write Functions + +void _mm_write_M_UWORD(UWORD data,FILE *fp) +{ + _mm_write_UBYTE(data&0xff,fp); + _mm_write_UBYTE(data>>8,fp); +} + + +void _mm_write_I_UWORD(UWORD data,FILE *fp) +{ + _mm_write_UBYTE(data>>8,fp); + _mm_write_UBYTE(data&0xff,fp); +} + + +void _mm_write_M_ULONG(ULONG data,FILE *fp) +{ + _mm_write_M_UWORD(data&0xffff,fp); + _mm_write_M_UWORD(data>>16,fp); +} + + +void _mm_write_I_ULONG(ULONG data,FILE *fp) +{ + _mm_write_I_UWORD(data>>16,fp); + _mm_write_I_UWORD(data&0xffff,fp); +} + +#else + +// --> Little Endian Write Functions + +void _mm_write_M_UWORD(UWORD data,FILE *fp) +{ + _mm_write_UBYTE(data>>8,fp); + _mm_write_UBYTE(data&0xff,fp); +} + + +void _mm_write_I_UWORD(UWORD data,FILE *fp) +{ + _mm_write_UBYTE(data&0xff,fp); + _mm_write_UBYTE(data>>8,fp); +} + + +void _mm_write_M_ULONG(ULONG data,FILE *fp) +{ + _mm_write_M_UWORD(data>>16,fp); + _mm_write_M_UWORD(data&0xffff,fp); +} + + +void _mm_write_I_ULONG(ULONG data,FILE *fp) +{ + _mm_write_I_UWORD(data&0xffff,fp); + _mm_write_I_UWORD(data>>16,fp); +} + +#endif + + +void _mm_write_M_SWORD(SWORD data,FILE *fp) +{ + _mm_write_M_UWORD((UWORD)data,fp); +} + + +void _mm_write_I_SWORD(SWORD data,FILE *fp) +{ + _mm_write_I_UWORD((UWORD)data,fp); +} + + +void _mm_write_M_SLONG(SLONG data,FILE *fp) +{ + _mm_write_M_ULONG((ULONG)data,fp); +} + + +void _mm_write_I_SLONG(SLONG data,FILE *fp) +{ + _mm_write_I_ULONG((ULONG)data,fp); +} + + +#define DEFINE_MULTIPLE_WRITE_FUNCTION(type_name, type) \ +void \ +_mm_write_##type_name##S (type *buffer, int number, FILE *fp) \ +{ \ + while(number>0) \ + { _mm_write_##type_name(*(buffer++),fp); \ + number--; \ + } \ +} + +//DEFINE_MULTIPLE_WRITE_FUNCTION (SBYTE, SBYTE) +//DEFINE_MULTIPLE_WRITE_FUNCTION (UBYTE, UBYTE) + +DEFINE_MULTIPLE_WRITE_FUNCTION (M_SWORD, SWORD) +DEFINE_MULTIPLE_WRITE_FUNCTION (M_UWORD, UWORD) +DEFINE_MULTIPLE_WRITE_FUNCTION (I_SWORD, SWORD) +DEFINE_MULTIPLE_WRITE_FUNCTION (I_UWORD, UWORD) + +DEFINE_MULTIPLE_WRITE_FUNCTION (M_SLONG, SLONG) +DEFINE_MULTIPLE_WRITE_FUNCTION (M_ULONG, ULONG) +DEFINE_MULTIPLE_WRITE_FUNCTION (I_SLONG, SLONG) +DEFINE_MULTIPLE_WRITE_FUNCTION (I_ULONG, ULONG) + + +/********** +SBYTE _mm_read_SBYTE(FILE *fp) +{ + return(fgetc(fp)); +} + +UBYTE _mm_read_UBYTE(FILE *fp) +{ + return(fgetc(fp)); +} +**********/ + + +#ifdef MM_BIG_ENDIAN + +UWORD _mm_read_I_UWORD(FILE *fp) +{ + UWORD result=((UWORD)_mm_read_UBYTE(fp))<<8; + result|=_mm_read_UBYTE(fp); + return result; +} + +UWORD _mm_read_M_UWORD(FILE *fp) +{ + UWORD result=_mm_read_UBYTE(fp); + result|=((UWORD)_mm_read_UBYTE(fp))<<8; + return result; +} + +ULONG _mm_read_I_ULONG(FILE *fp) +{ + ULONG result=((ULONG)_mm_read_M_UWORD(fp))<<16; + result|=_mm_read_M_UWORD(fp); + return result; +} + +ULONG _mm_read_M_ULONG(FILE *fp) +{ + ULONG result=_mm_read_I_UWORD(fp); + result|=((ULONG)_mm_read_I_UWORD(fp))<<16; + return result; +} + +#else + +UWORD _mm_read_M_UWORD(FILE *fp) +{ + UWORD result=((UWORD)_mm_read_UBYTE(fp))<<8; + result|=_mm_read_UBYTE(fp); + return result; +} + +UWORD _mm_read_I_UWORD(FILE *fp) +{ + UWORD result=_mm_read_UBYTE(fp); + result|=((UWORD)_mm_read_UBYTE(fp))<<8; + return result; +} + +ULONG _mm_read_M_ULONG(FILE *fp) +{ + ULONG result=((ULONG)_mm_read_M_UWORD(fp))<<16; + result|=_mm_read_M_UWORD(fp); + return result; +} + +ULONG _mm_read_I_ULONG(FILE *fp) +{ + ULONG result=_mm_read_I_UWORD(fp); + result|=((ULONG)_mm_read_I_UWORD(fp))<<16; + return result; +} + +#endif + +SWORD _mm_read_M_SWORD(FILE *fp) +{ + return((SWORD)_mm_read_M_UWORD(fp)); +} + +SWORD _mm_read_I_SWORD(FILE *fp) +{ + return((SWORD)_mm_read_I_UWORD(fp)); +} + +SLONG _mm_read_M_SLONG(FILE *fp) +{ + return((SLONG)_mm_read_M_ULONG(fp)); +} + +SLONG _mm_read_I_SLONG(FILE *fp) +{ + return((SLONG)_mm_read_I_ULONG(fp)); +} + + +int _mm_read_string(CHAR *buffer, int number, FILE *fp) +{ + fread(buffer,1,number,fp); + return !feof(fp); +} + + + +#define DEFINE_MULTIPLE_READ_FUNCTION(type_name, type) \ +int \ +_mm_read_##type_name##S (type *buffer, int number, FILE *fp) \ +{ \ + while(number>0) \ + { *(buffer++)=_mm_read_##type_name(fp); \ + number--; \ + } \ + return !feof(fp); \ +} + +//DEFINE_MULTIPLE_READ_FUNCTION (SBYTE, SBYTE) +//DEFINE_MULTIPLE_READ_FUNCTION (UBYTE, UBYTE) + +DEFINE_MULTIPLE_READ_FUNCTION (M_SWORD, SWORD) +DEFINE_MULTIPLE_READ_FUNCTION (M_UWORD, UWORD) +DEFINE_MULTIPLE_READ_FUNCTION (I_SWORD, SWORD) +DEFINE_MULTIPLE_READ_FUNCTION (I_UWORD, UWORD) + +DEFINE_MULTIPLE_READ_FUNCTION (M_SLONG, SLONG) +DEFINE_MULTIPLE_READ_FUNCTION (M_ULONG, ULONG) +DEFINE_MULTIPLE_READ_FUNCTION (I_SLONG, SLONG) +DEFINE_MULTIPLE_READ_FUNCTION (I_ULONG, ULONG) +