- fixed typos in csprite's code generator for nasm
[dosdemo] / libs / mikmod / include / mikmod_internals.h
1 /*      MikMod sound library
2         (c) 1998, 1999, 2005 Miodrag Vallat and others - see file AUTHORS for
3         complete list.
4
5         This library is free software; you can redistribute it and/or modify
6         it under the terms of the GNU Library General Public License as
7         published by the Free Software Foundation; either version 2 of
8         the License, or (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13         GNU Library General Public License for more details.
14
15         You should have received a copy of the GNU Library General Public
16         License along with this library; if not, write to the Free Software
17         Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18         02111-1307, USA.
19 */
20
21 /*==============================================================================
22
23   MikMod sound library internal definitions
24
25   ==============================================================================*/
26
27 #ifndef _MIKMOD_INTERNALS_H
28 #define _MIKMOD_INTERNALS_H
29
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33
34 #include <stdarg.h>
35
36 #if defined(_MSC_VER) && !defined(__cplusplus) && !defined(HAVE_CONFIG_H)
37 #define inline __inline
38 #endif
39
40 #ifndef MIKMOD_UNIX
41 #if (defined(unix) || defined(__unix__) || defined(__unix) || \
42         (defined(__APPLE__) && defined(__MACH__))) && \
43    !(defined(__DJGPP__) || defined(_WIN32) || defined(__OS2__) || defined(__EMX__))
44 #define MIKMOD_UNIX 1
45 #endif
46 #endif /* MIKMOD_UNIX */
47
48 #include "mikmod.h"
49
50 /*========== More type definitions */
51
52 /* SLONGLONG: 64bit, signed */
53 #if !defined(_WIN32) && \
54    (defined(_LP64) || defined(__LP64__) || defined(__arch64__) || defined(__alpha) || defined(__x64_64) || defined(__powerpc64__))
55 typedef long            SLONGLONG;
56 #define NATIVE_64BIT_INT
57 #elif defined(_WIN64) /* win64 is LLP64, not LP64  */
58 #define NATIVE_64BIT_INT
59 typedef long long       SLONGLONG;
60 #elif defined(__WATCOMC__)
61 typedef __int64         SLONGLONG;
62 #elif defined(_WIN32) && !defined(__MWERKS__)
63 typedef LONGLONG        SLONGLONG;
64 #elif defined(macintosh) && !TYPE_LONGLONG
65 #include <Types.h>
66 typedef SInt64          SLONGLONG;
67 #else
68 typedef long long       SLONGLONG;
69 #endif
70 typedef int __s64_typetest [(sizeof(SLONGLONG)==8) * 2 - 1];
71
72 /* pointer-sized signed int (ssize_t/intptr_t) : */
73 #if defined(_WIN64) /* win64 is LLP64, not LP64  */
74 typedef long long       SINTPTR_T;
75 #else
76 /* long should be pointer-sized for all others : */
77 typedef long            SINTPTR_T;
78 #endif
79 typedef int __iptr_typetest [(sizeof(SINTPTR_T)==sizeof(void*)) * 2 - 1];
80
81 /*========== Error handling */
82
83 #define _mm_errno MikMod_errno
84 #define _mm_critical MikMod_critical
85 extern MikMod_handler_t _mm_errorhandler;
86
87 /*========== MT stuff */
88
89 #ifdef HAVE_PTHREAD
90 #include <pthread.h>
91 #define DECLARE_MUTEX(name) \
92         extern pthread_mutex_t _mm_mutex_##name
93 #define MUTEX_LOCK(name)    \
94         pthread_mutex_lock(&_mm_mutex_##name)
95 #define MUTEX_UNLOCK(name)  \
96         pthread_mutex_unlock(&_mm_mutex_##name)
97
98 #elif defined(__OS2__)||defined(__EMX__)
99 #define DECLARE_MUTEX(name) \
100         extern HMTX _mm_mutex_##name
101 #define MUTEX_LOCK(name)    \
102         if(_mm_mutex_##name)\
103             DosRequestMutexSem(_mm_mutex_##name,SEM_INDEFINITE_WAIT)
104 #define MUTEX_UNLOCK(name)  \
105         if(_mm_mutex_##name)\
106             DosReleaseMutexSem(_mm_mutex_##name)
107
108 #elif defined(_WIN32)
109 #include <windows.h>
110 #define DECLARE_MUTEX(name) \
111         extern HANDLE _mm_mutex_##name
112 #define MUTEX_LOCK(name)    \
113         if(_mm_mutex_##name)\
114             WaitForSingleObject(_mm_mutex_##name,INFINITE)
115 #define MUTEX_UNLOCK(name)  \
116         if(_mm_mutex_##name)\
117             ReleaseMutex(_mm_mutex_##name)
118
119 #else
120 #define DECLARE_MUTEX(name) \
121         extern void *_mm_mutex_##name
122 #define MUTEX_LOCK(name)
123 #define MUTEX_UNLOCK(name)
124 #endif
125
126 DECLARE_MUTEX(lists);
127 DECLARE_MUTEX(vars);
128
129 /*========== Replacement funcs */
130
131 extern int _mm_strcasecmp (const char *__s1, const char *__s2);
132
133 /*========== Portable file I/O */
134
135 extern MREADER* _mm_new_mem_reader(const void *buffer, long len);
136 extern void _mm_delete_mem_reader(MREADER *reader);
137
138 extern MREADER* _mm_new_file_reader(FILE* fp);
139 extern void _mm_delete_file_reader(MREADER*);
140
141 extern MWRITER* _mm_new_file_writer(FILE *fp);
142 extern void _mm_delete_file_writer(MWRITER*);
143
144 extern BOOL _mm_FileExists(const CHAR *fname);
145
146 #define _mm_write_SBYTE(x,y)    y->Put(y,(int)x)
147 #define _mm_write_UBYTE(x,y)    y->Put(y,(int)x)
148
149 #define _mm_read_SBYTE(x)       (SBYTE)x->Get(x)
150 #define _mm_read_UBYTE(x)       (UBYTE)x->Get(x)
151 #define _mm_skip_BYTE(x)        (void)x->Get(x)
152
153 #define _mm_write_SBYTES(x,y,z) z->Write(z,(const void *)x,y)
154 #define _mm_write_UBYTES(x,y,z) z->Write(z,(const void *)x,y)
155 #define _mm_read_SBYTES(x,y,z)  z->Read(z,(void *)x,y)
156 #define _mm_read_UBYTES(x,y,z)  z->Read(z,(void *)x,y)
157
158 #define _mm_fseek(x,y,z)        x->Seek(x,y,z)
159 #define _mm_ftell(x)            x->Tell(x)
160 #define _mm_rewind(x)           _mm_fseek(x,0,SEEK_SET)
161
162 #define _mm_eof(x)              x->Eof(x)
163
164 extern void _mm_iobase_setcur(MREADER*);
165 extern void _mm_iobase_revert(MREADER*);
166 extern FILE* _mm_fopen(const CHAR *, const CHAR *);
167 extern int  _mm_fclose(FILE *);
168 extern void _mm_write_string(const CHAR*,MWRITER*);
169 extern BOOL _mm_read_string (CHAR*,int,MREADER*);
170
171 extern SWORD _mm_read_M_SWORD(MREADER*);
172 extern SWORD _mm_read_I_SWORD(MREADER*);
173 extern UWORD _mm_read_M_UWORD(MREADER*);
174 extern UWORD _mm_read_I_UWORD(MREADER*);
175
176 extern SLONG _mm_read_M_SLONG(MREADER*);
177 extern SLONG _mm_read_I_SLONG(MREADER*);
178 extern ULONG _mm_read_M_ULONG(MREADER*);
179 extern ULONG _mm_read_I_ULONG(MREADER*);
180
181 extern BOOL _mm_read_M_SWORDS(SWORD*,int,MREADER*);
182 extern BOOL _mm_read_I_SWORDS(SWORD*,int,MREADER*);
183 extern BOOL _mm_read_M_UWORDS(UWORD*,int,MREADER*);
184 extern BOOL _mm_read_I_UWORDS(UWORD*,int,MREADER*);
185
186 extern BOOL _mm_read_M_SLONGS(SLONG*,int,MREADER*);
187 extern BOOL _mm_read_I_SLONGS(SLONG*,int,MREADER*);
188 extern BOOL _mm_read_M_ULONGS(ULONG*,int,MREADER*);
189 extern BOOL _mm_read_I_ULONGS(ULONG*,int,MREADER*);
190
191 extern void _mm_write_M_SWORD(SWORD,MWRITER*);
192 extern void _mm_write_I_SWORD(SWORD,MWRITER*);
193 extern void _mm_write_M_UWORD(UWORD,MWRITER*);
194 extern void _mm_write_I_UWORD(UWORD,MWRITER*);
195
196 extern void _mm_write_M_SLONG(SLONG,MWRITER*);
197 extern void _mm_write_I_SLONG(SLONG,MWRITER*);
198 extern void _mm_write_M_ULONG(ULONG,MWRITER*);
199 extern void _mm_write_I_ULONG(ULONG,MWRITER*);
200
201 extern void _mm_write_M_SWORDS(SWORD*,int,MWRITER*);
202 extern void _mm_write_I_SWORDS(SWORD*,int,MWRITER*);
203 extern void _mm_write_M_UWORDS(UWORD*,int,MWRITER*);
204 extern void _mm_write_I_UWORDS(UWORD*,int,MWRITER*);
205
206 extern void _mm_write_M_SLONGS(SLONG*,int,MWRITER*);
207 extern void _mm_write_I_SLONGS(SLONG*,int,MWRITER*);
208 extern void _mm_write_M_ULONGS(ULONG*,int,MWRITER*);
209 extern void _mm_write_I_ULONGS(ULONG*,int,MWRITER*);
210
211 /*========== Samples */
212
213 /* This is a handle of sorts attached to any sample registered with
214    SL_RegisterSample.  Generally, this only need be used or changed by the
215    loaders and drivers of mikmod. */
216 typedef struct SAMPLOAD {
217     struct SAMPLOAD *next;
218
219     ULONG    length;       /* length of sample (in samples!) */
220     ULONG    loopstart;    /* repeat position (relative to start, in samples) */
221     ULONG    loopend;      /* repeat end */
222     UWORD    infmt,outfmt;
223     int      scalefactor;
224     SAMPLE*  sample;
225     MREADER* reader;
226 } SAMPLOAD;
227
228 /*========== Sample and waves loading interface */
229
230 extern void      SL_HalveSample(SAMPLOAD*,int);
231 extern void      SL_Sample8to16(SAMPLOAD*);
232 extern void      SL_Sample16to8(SAMPLOAD*);
233 extern void      SL_SampleSigned(SAMPLOAD*);
234 extern void      SL_SampleUnsigned(SAMPLOAD*);
235 extern int       SL_LoadSamples(void);
236 extern SAMPLOAD* SL_RegisterSample(SAMPLE*,int,MREADER*);
237 extern int       SL_Load(void*,SAMPLOAD*,ULONG);
238 extern BOOL      SL_Init(SAMPLOAD*);
239 extern void      SL_Exit(SAMPLOAD*);
240
241 /*========== Internal module representation (UniMod) interface */
242
243 /* number of notes in an octave */
244 #define OCTAVE 12
245
246 extern void   UniSetRow(UBYTE*);
247 extern UBYTE  UniGetByte(void);
248 extern UWORD  UniGetWord(void);
249 extern UBYTE* UniFindRow(UBYTE*,UWORD);
250 extern void   UniSkipOpcode(void);
251 extern void   UniReset(void);
252 extern void   UniWriteByte(UBYTE);
253 extern void   UniWriteWord(UWORD);
254 extern void   UniNewline(void);
255 extern UBYTE* UniDup(void);
256 extern BOOL   UniInit(void);
257 extern void   UniCleanup(void);
258 extern void   UniEffect(UWORD,UWORD);
259 #define UniInstrument(x)   UniEffect(UNI_INSTRUMENT,x)
260 #define UniNote(x)         UniEffect(UNI_NOTE,x)
261 extern void   UniPTEffect(UBYTE,UBYTE);
262 extern void   UniVolEffect(UWORD,UBYTE);
263
264 /*========== Module Commands */
265
266 enum {
267  /* Simple note */
268     UNI_NOTE = 1,
269  /* Instrument change */
270     UNI_INSTRUMENT,
271  /* Protracker effects */
272     UNI_PTEFFECT0,  /* arpeggio */
273     UNI_PTEFFECT1,  /* porta up */
274     UNI_PTEFFECT2,  /* porta down */
275     UNI_PTEFFECT3,  /* porta to note */
276     UNI_PTEFFECT4,  /* vibrato */
277     UNI_PTEFFECT5,  /* dual effect 3+A */
278     UNI_PTEFFECT6,  /* dual effect 4+A */
279     UNI_PTEFFECT7,  /* tremolo */
280     UNI_PTEFFECT8,  /* pan */
281     UNI_PTEFFECT9,  /* sample offset */
282     UNI_PTEFFECTA,  /* volume slide */
283     UNI_PTEFFECTB,  /* pattern jump */
284     UNI_PTEFFECTC,  /* set volume */
285     UNI_PTEFFECTD,  /* pattern break */
286     UNI_PTEFFECTE,  /* extended effects */
287     UNI_PTEFFECTF,  /* set speed */
288  /* Scream Tracker effects */
289     UNI_S3MEFFECTA, /* set speed */
290     UNI_S3MEFFECTD, /* volume slide */
291     UNI_S3MEFFECTE, /* porta down */
292     UNI_S3MEFFECTF, /* porta up */
293     UNI_S3MEFFECTI, /* tremor */
294     UNI_S3MEFFECTQ, /* retrig */
295     UNI_S3MEFFECTR, /* tremolo */
296     UNI_S3MEFFECTT, /* set tempo */
297     UNI_S3MEFFECTU, /* fine vibrato */
298     UNI_KEYOFF,     /* note off */
299  /* Fast Tracker effects */
300     UNI_KEYFADE,    /* note fade */
301     UNI_VOLEFFECTS, /* volume column effects */
302     UNI_XMEFFECT4,  /* vibrato */
303     UNI_XMEFFECT6,  /* dual effect 4+A */
304     UNI_XMEFFECTA,  /* volume slide */
305     UNI_XMEFFECTE1, /* fine porta up */
306     UNI_XMEFFECTE2, /* fine porta down */
307     UNI_XMEFFECTEA, /* fine volume slide up */
308     UNI_XMEFFECTEB, /* fine volume slide down */
309     UNI_XMEFFECTG,  /* set global volume */
310     UNI_XMEFFECTH,  /* global volume slide */
311     UNI_XMEFFECTL,  /* set envelope position */
312     UNI_XMEFFECTP,  /* pan slide */
313     UNI_XMEFFECTX1, /* extra fine porta up */
314     UNI_XMEFFECTX2, /* extra fine porta down */
315  /* Impulse Tracker effects */
316     UNI_ITEFFECTG,  /* porta to note */
317     UNI_ITEFFECTH,  /* vibrato */
318     UNI_ITEFFECTI,  /* tremor (xy not incremented) */
319     UNI_ITEFFECTM,  /* set channel volume */
320     UNI_ITEFFECTN,  /* slide / fineslide channel volume */
321     UNI_ITEFFECTP,  /* slide / fineslide channel panning */
322     UNI_ITEFFECTT,  /* slide tempo */
323     UNI_ITEFFECTU,  /* fine vibrato */
324     UNI_ITEFFECTW,  /* slide / fineslide global volume */
325     UNI_ITEFFECTY,  /* panbrello */
326     UNI_ITEFFECTZ,  /* resonant filters */
327     UNI_ITEFFECTS0,
328  /* UltraTracker effects */
329     UNI_ULTEFFECT9, /* Sample fine offset */
330  /* OctaMED effects */
331     UNI_MEDSPEED,
332     UNI_MEDEFFECTF1,/* play note twice */
333     UNI_MEDEFFECTF2,/* delay note */
334     UNI_MEDEFFECTF3,/* play note three times */
335  /* Oktalyzer effects */
336     UNI_OKTARP,     /* arpeggio */
337
338     UNI_LAST
339 };
340
341 extern const UWORD unioperands[UNI_LAST];
342
343 /* IT / S3M Extended SS effects: */
344 enum {
345     SS_GLISSANDO = 1,
346     SS_FINETUNE,
347     SS_VIBWAVE,
348     SS_TREMWAVE,
349     SS_PANWAVE,
350     SS_FRAMEDELAY,
351     SS_S7EFFECTS,
352     SS_PANNING,
353     SS_SURROUND,
354     SS_HIOFFSET,
355     SS_PATLOOP,
356     SS_NOTECUT,
357     SS_NOTEDELAY,
358     SS_PATDELAY
359 };
360
361 /* IT Volume column effects */
362 enum {
363     VOL_VOLUME = 1,
364     VOL_PANNING,
365     VOL_VOLSLIDE,
366     VOL_PITCHSLIDEDN,
367     VOL_PITCHSLIDEUP,
368     VOL_PORTAMENTO,
369     VOL_VIBRATO
370 };
371
372 /* IT resonant filter information */
373
374 #define UF_MAXMACRO     0x10
375 #define UF_MAXFILTER    0x100
376
377 #define FILT_CUT        0x80
378 #define FILT_RESONANT   0x81
379
380 typedef struct FILTER {
381     UBYTE filter,inf;
382 } FILTER;
383
384 /*========== Instruments */
385
386 /* Instrument format flags */
387 #define IF_OWNPAN       1
388 #define IF_PITCHPAN     2
389
390 /* Envelope flags: */
391 #define EF_ON           1
392 #define EF_SUSTAIN      2
393 #define EF_LOOP         4
394 #define EF_VOLENV       8
395
396 /* New Note Action Flags */
397 #define NNA_CUT         0
398 #define NNA_CONTINUE    1
399 #define NNA_OFF         2
400 #define NNA_FADE        3
401
402 #define NNA_MASK        3
403
404 #define DCT_OFF         0
405 #define DCT_NOTE        1
406 #define DCT_SAMPLE      2
407 #define DCT_INST        3
408
409 #define DCA_CUT         0
410 #define DCA_OFF         1
411 #define DCA_FADE        2
412
413 #define KEY_KICK        0
414 #define KEY_OFF         1
415 #define KEY_FADE        2
416 #define KEY_KILL        (KEY_OFF|KEY_FADE)
417
418 #define KICK_ABSENT     0
419 #define KICK_NOTE       1
420 #define KICK_KEYOFF     2
421 #define KICK_ENV        4
422
423 #define AV_IT           1   /* IT vs. XM vibrato info */
424
425 /*========== Playing */
426
427 #define POS_NONE        (-2)    /* no loop position defined */
428
429 #define LAST_PATTERN    (UWORD)(-1) /* special ``end of song'' pattern */
430
431 typedef struct ENVPR {
432     UBYTE  flg;     /* envelope flag */
433     UBYTE  pts;     /* number of envelope points */
434     UBYTE  susbeg;  /* envelope sustain index begin */
435     UBYTE  susend;  /* envelope sustain index end */
436     UBYTE  beg;     /* envelope loop begin */
437     UBYTE  end;     /* envelope loop end */
438     SWORD  p;       /* current envelope counter */
439     UWORD  a;       /* envelope index a */
440     UWORD  b;       /* envelope index b */
441     ENVPT* env;     /* envelope points */
442 } ENVPR;
443
444 typedef struct MP_CHANNEL {
445     INSTRUMENT* i;
446     SAMPLE *s;
447     UBYTE  sample;      /* which sample number */
448     UBYTE  note;        /* the audible note as heard, direct rep of period */
449     SWORD  outvolume;   /* output volume (vol + sampcol + instvol) */
450     SBYTE  chanvol;     /* channel's "global" volume */
451     UWORD  fadevol;     /* fading volume rate */
452     SWORD  panning;     /* panning position */
453     UBYTE  kick;        /* if true = sample has to be restarted */
454     UBYTE  kick_flag;   /* kick has been true */
455     UWORD  period;      /* period to play the sample at */
456     UBYTE  nna;         /* New note action type + master/slave flags */
457
458     UBYTE  volflg;      /* volume envelope settings */
459     UBYTE  panflg;      /* panning envelope settings */
460     UBYTE  pitflg;      /* pitch envelope settings */
461
462     UBYTE  keyoff;      /* if true = fade out and stuff */
463     SWORD  handle;      /* which sample-handle */
464     UBYTE  notedelay;   /* (used for note delay) */
465     SLONG  start;       /* The starting byte index in the sample */
466 } MP_CHANNEL;
467
468 typedef struct MP_CONTROL {
469     struct MP_CHANNEL   main;
470
471     struct MP_VOICE*    slave;  /* Audio Slave of current effects control channel */
472
473     UBYTE   slavechn;   /* Audio Slave of current effects control channel */
474     UBYTE   muted;      /* if set, channel not played */
475     UWORD   ultoffset;  /* fine sample offset memory */
476     UBYTE   anote;      /* the note that indexes the audible */
477     UBYTE   oldnote;
478     SWORD   ownper;
479     SWORD   ownvol;
480     UBYTE   dca;        /* duplicate check action */
481     UBYTE   dct;        /* duplicate check type */
482     UBYTE*  row;        /* row currently playing on this channel */
483     SBYTE   retrig;     /* retrig value (0 means don't retrig) */
484     ULONG   speed;      /* what finetune to use */
485     SWORD   volume;     /* amiga volume (0 t/m 64) to play the sample at */
486
487     SWORD   tmpvolume;  /* tmp volume */
488     UWORD   tmpperiod;  /* tmp period */
489     UWORD   wantedperiod;/* period to slide to (with effect 3 or 5) */
490
491     UBYTE   arpmem;     /* arpeggio command memory */
492     UBYTE   pansspd;    /* panslide speed */
493     UWORD   slidespeed;
494     UWORD   portspeed;  /* noteslide speed (toneportamento) */
495
496     UBYTE   s3mtremor;  /* s3m tremor (effect I) counter */
497     UBYTE   s3mtronof;  /* s3m tremor ontime/offtime */
498     UBYTE   s3mvolslide;/* last used volslide */
499     SBYTE   sliding;
500     UBYTE   s3mrtgspeed;/* last used retrig speed */
501     UBYTE   s3mrtgslide;/* last used retrig slide */
502
503     UBYTE   glissando;  /* glissando (0 means off) */
504     UBYTE   wavecontrol;
505
506     SBYTE   vibpos;     /* current vibrato position */
507     UBYTE   vibspd;     /* "" speed */
508     UBYTE   vibdepth;   /* "" depth */
509
510     SBYTE   trmpos;     /* current tremolo position */
511     UBYTE   trmspd;     /* "" speed */
512     UBYTE   trmdepth;   /* "" depth */
513
514     UBYTE   fslideupspd;
515     UBYTE   fslidednspd;
516     UBYTE   fportupspd; /* fx E1 (extra fine portamento up) data */
517     UBYTE   fportdnspd; /* fx E2 (extra fine portamento dn) data */
518     UBYTE   ffportupspd;/* fx X1 (extra fine portamento up) data */
519     UBYTE   ffportdnspd;/* fx X2 (extra fine portamento dn) data */
520
521     ULONG   hioffset;   /* last used high order of sample offset */
522     UWORD   soffset;    /* last used low order of sample-offset (effect 9) */
523
524     UBYTE   sseffect;   /* last used Sxx effect */
525     UBYTE   ssdata;     /* last used Sxx data info */
526     UBYTE   chanvolslide;/* last used channel volume slide */
527
528     UBYTE   panbwave;   /* current panbrello waveform */
529     UBYTE   panbpos;    /* current panbrello position */
530     SBYTE   panbspd;    /* "" speed */
531     UBYTE   panbdepth;  /* "" depth */
532
533     UWORD   newsamp;    /* set to 1 upon a sample / inst change */
534     UBYTE   voleffect;  /* Volume Column Effect Memory as used by IT */
535     UBYTE   voldata;    /* Volume Column Data Memory */
536
537     SWORD   pat_reppos; /* patternloop position */
538     UWORD   pat_repcnt; /* times to loop */
539 } MP_CONTROL;
540
541 /* Used by NNA only player (audio control.  AUDTMP is used for full effects
542    control). */
543 typedef struct MP_VOICE {
544     struct MP_CHANNEL   main;
545
546     ENVPR   venv;
547     ENVPR   penv;
548     ENVPR   cenv;
549
550     UWORD   avibpos;    /* autovibrato pos */
551     UWORD   aswppos;    /* autovibrato sweep pos */
552
553     ULONG   totalvol;   /* total volume of channel (before global mixings) */
554
555     BOOL    mflag;
556     SWORD   masterchn;
557     UWORD   masterperiod;
558
559     MP_CONTROL* master; /* index of "master" effects channel */
560 } MP_VOICE;
561
562 /*========== Loaders */
563
564 typedef struct MLOADER {
565     struct MLOADER*     next;
566     const CHAR* type;
567     const CHAR* version;
568     BOOL  (*Init)(void);
569     BOOL  (*Test)(void);
570     BOOL  (*Load)(BOOL);
571     void  (*Cleanup)(void);
572     CHAR* (*LoadTitle)(void);
573 } MLOADER;
574
575 /* internal loader variables */
576 extern MREADER* modreader;
577 extern MODULE  of;                  /* static unimod loading space */
578 extern const UWORD finetune[16];
579 extern const UWORD npertab[7*OCTAVE];/* used by the original MOD loaders */
580
581 extern SBYTE   remap[UF_MAXCHAN];   /* for removing empty channels */
582 extern UBYTE*  poslookup;           /* lookup table for pattern jumps after
583                                        blank pattern removal */
584 extern UWORD   poslookupcnt;
585 extern UWORD*  origpositions;
586
587 extern BOOL    filters;             /* resonant filters in use */
588 extern UBYTE   activemacro;         /* active midi macro number for Sxx */
589 extern UBYTE   filtermacros[UF_MAXMACRO];    /* midi macro settings */
590 extern FILTER  filtersettings[UF_MAXFILTER]; /* computed filter settings */
591
592 extern int*    noteindex;
593
594 /*========== Internal loader interface */
595
596 extern BOOL   ReadComment(UWORD);
597 extern BOOL   ReadLinedComment(UWORD,UWORD);
598 extern BOOL   AllocPositions(int);
599 extern BOOL   AllocPatterns(void);
600 extern BOOL   AllocTracks(void);
601 extern BOOL   AllocInstruments(void);
602 extern BOOL   AllocSamples(void);
603 extern CHAR*  DupStr(const CHAR*, UWORD, BOOL);
604
605 /* loader utility functions */
606 extern int*   AllocLinear(void);
607 extern void   FreeLinear(void);
608 extern int    speed_to_finetune(ULONG,int);
609 extern void   S3MIT_ProcessCmd(UBYTE,UBYTE,unsigned int);
610 extern void   S3MIT_CreateOrders(BOOL);
611
612 /* flags for S3MIT_ProcessCmd */
613 #define S3MIT_OLDSTYLE  1   /* behave as old scream tracker */
614 #define S3MIT_IT        2   /* behave as impulse tracker */
615 #define S3MIT_SCREAM    4   /* enforce scream tracker specific limits */
616
617 /* used to convert c4spd to linear XM periods (IT and IMF loaders). */
618 extern UWORD  getlinearperiod(UWORD,ULONG);
619 extern ULONG  getfrequency(UWORD,ULONG);
620
621 /* loader shared data */
622 #define STM_NTRACKERS   3
623 extern const CHAR *STM_Signatures[STM_NTRACKERS];
624
625 /*========== Player interface */
626
627 extern int    Player_Init(MODULE*);
628 extern void   Player_Exit(MODULE*);
629 extern void   Player_HandleTick(void);
630
631 /*========== UnPackers */
632
633 typedef BOOL (*MUNPACKER) (struct MREADER*,
634                            void** /* unpacked data out */ ,
635                            long* /* unpacked data size */ );
636 extern BOOL PP20_Unpack(MREADER*, void**, long*);
637 extern BOOL MMCMP_Unpack(MREADER*, void**, long*);
638 extern BOOL XPK_Unpack(MREADER*, void**, long*);
639 extern BOOL S404_Unpack(MREADER*, void**, long*);
640
641 /*========== Drivers */
642
643 /* max. number of handles a driver has to provide. (not strict) */
644 #define MAXSAMPLEHANDLES    384
645
646 /* These variables can be changed at ANY time and results will be immediate */
647 extern UWORD md_bpm;         /* current song / hardware BPM rate */
648
649 /* Variables below can be changed via MD_SetNumVoices at any time. However, a
650    call to MD_SetNumVoicess while the driver is active will cause the sound to
651    skip slightly. */
652 extern UBYTE md_numchn;      /* number of song + sound effects voices */
653 extern UBYTE md_sngchn;      /* number of song voices */
654 extern UBYTE md_sfxchn;      /* number of sound effects voices */
655 extern UBYTE md_hardchn;     /* number of hardware mixed voices */
656 extern UBYTE md_softchn;     /* number of software mixed voices */
657
658 /* This is for use by the hardware drivers only.  It points to the registered
659    tickhandler function. */
660 extern void (*md_player)(void);
661
662 extern SWORD  MD_SampleLoad(SAMPLOAD*,int);
663 extern void   MD_SampleUnload(SWORD);
664 extern ULONG  MD_SampleSpace(int);
665 extern ULONG  MD_SampleLength(int,SAMPLE*);
666
667 /* uLaw conversion */
668 extern void unsignedtoulaw(char *,int);
669
670 /* Parameter extraction helper */
671 extern CHAR  *MD_GetAtom(const CHAR*, const CHAR*, BOOL);
672
673 /* Internal software mixer stuff */
674 extern void VC_SetupPointers(void);
675 extern int  VC1_Init(void);
676 extern int  VC2_Init(void);
677
678 #if (MIKMOD_UNIX)
679 /* POSIX helper functions */
680 extern BOOL MD_Access(const CHAR *);
681 extern int  MD_DropPrivileges(void);
682 #endif
683
684 /* Macro to define a missing driver, yet allowing binaries to dynamically link
685    with the library without missing symbol errors */
686 #define MISSING(a) MDRIVER a = { NULL, NULL, NULL, 0, 0 }
687
688 /*========== Prototypes for non-MT safe versions of some public functions */
689
690 extern void _mm_registerdriver(struct MDRIVER*);
691 extern void _mm_registerloader(struct MLOADER*);
692 extern BOOL MikMod_Active_internal(void);
693 extern void MikMod_DisableOutput_internal(void);
694 extern int  MikMod_EnableOutput_internal(void);
695 extern void MikMod_Exit_internal(void);
696 extern int  MikMod_SetNumVoices_internal(int,int);
697 extern void Player_Exit_internal(MODULE*);
698 extern void Player_Stop_internal(void);
699 extern BOOL Player_Paused_internal(void);
700 extern void Sample_Free_internal(SAMPLE*);
701 extern void Voice_Play_internal(SBYTE,SAMPLE*,ULONG);
702 extern void Voice_SetFrequency_internal(SBYTE,ULONG);
703 extern void Voice_SetPanning_internal(SBYTE,ULONG);
704 extern void Voice_SetVolume_internal(SBYTE,UWORD);
705 extern void Voice_Stop_internal(SBYTE);
706 extern BOOL Voice_Stopped_internal(SBYTE);
707
708 extern int   VC1_PlayStart(void);
709 extern int   VC2_PlayStart(void);
710 extern void  VC1_PlayStop(void);
711 extern void  VC2_PlayStop(void);
712 extern int  VC1_SetNumVoices(void);
713 extern int  VC2_SetNumVoices(void);
714
715 extern MikMod_callback_t vc_callback;
716
717 #ifdef __cplusplus
718 }
719 #endif
720
721 /*========== SIMD mixing routines */
722 #undef HAVE_ALTIVEC
723 #undef HAVE_SSE2
724 #if defined(MIKMOD_SIMD)
725
726 #if (defined(__ppc__) || defined(__ppc64__)) && defined(__VEC__) && !(defined(__GNUC__) && (__GNUC__ < 3))
727 #define HAVE_ALTIVEC
728
729 #elif defined(__GNUC__) && defined(__SSE2__) /* x86 / x86_64 */
730 #define HAVE_SSE2
731
732 #elif defined(_MSC_VER) && (_MSC_VER >= 1300) && (defined(_M_IX86) || defined(_M_AMD64))
733 /* FIXME: emmintrin.h requires VC6 processor pack or VC2003+ */
734 #define HAVE_SSE2
735 /* avoid some warnings */
736 #pragma warning(disable:4761)
737 #pragma warning(disable:4391)
738 #pragma warning(disable:4244)
739
740 #endif /* AltiVec/SSE2 */
741 #endif /* MIKMOD_SIMD */
742
743 /*========== SIMD mixing helper functions =============*/
744
745 #if defined(_WIN64)
746 # if defined(_MSC_VER)
747 #  define IS_ALIGNED_16(ptr) (!((__int64)(ptr) & 15i64))
748 # else /* GCC, LCC, .. */
749 #  define IS_ALIGNED_16(ptr) (!((long long)(ptr) & 15LL))
750 # endif
751 #else /* long cast should be OK for all else */
752 #define IS_ALIGNED_16(ptr) (!((long)(ptr) & 15L))
753 #endif
754
755 /* Altivec helper function */
756 #if defined HAVE_ALTIVEC
757
758 #define simd_m128i vector signed int
759 #define simd_m128 vector float
760
761 #ifdef __GNUC__
762 #include <ppc_intrinsics.h>
763 #endif
764
765 /* Helper functions */
766
767 /* Set single float across the four values */
768 static inline vector float vec_mul(const vector float a, const vector float b) {
769     return vec_madd(a, b, (const vector float)(0.f));
770 }
771
772 /* Set single float across the four values */
773 static inline vector float vec_load_ps1(const float *pF) {
774     vector float data = vec_lde(0, pF);
775     return vec_splat(vec_perm(data, data, vec_lvsl(0, pF)), 0);
776 }
777
778 /* Set vector to 0 */
779 static inline vector float vec_setzero() {
780     return (vector float) (0.);
781 }
782
783 static inline vector signed char vec_set1_8(unsigned char splatchar) {
784     vector unsigned char splatmap = vec_lvsl(0, &splatchar);
785     vector unsigned char result = vec_lde(0, &splatchar);
786     splatmap = vec_splat(splatmap, 0);
787     return (vector signed char)vec_perm(result, result, splatmap);
788 }
789
790 #define PERM_A0 0x00,0x01,0x02,0x03
791 #define PERM_A1 0x04,0x05,0x06,0x07
792 #define PERM_A2 0x08,0x09,0x0A,0x0B
793 #define PERM_A3 0x0C,0x0D,0x0E,0x0F
794 #define PERM_B0 0x10,0x11,0x12,0x13
795 #define PERM_B1 0x14,0x15,0x16,0x17
796 #define PERM_B2 0x18,0x19,0x1A,0x1B
797 #define PERM_B3 0x1C,0x1D,0x1E,0x1F
798
799 /* Equivalent to _mm_unpacklo_epi32 */
800 static inline vector signed int vec_unpacklo(vector signed int a, vector signed int b) {
801    return vec_perm(a, b, (vector unsigned char)(PERM_A0,PERM_A1,PERM_B0,PERM_B1));
802 }
803
804 /* Equivalent to _mm_srli_si128(a, 8) (without the zeroing in high part). */
805 static inline vector signed int vec_hiqq(vector signed int a) {
806    vector signed int b = vec_splat_s32(0);
807    return vec_perm(a, b, (vector unsigned char)(PERM_A2,PERM_A3,PERM_B2,PERM_B3));
808 }
809
810 /* vec_sra is max +15. We have to do in two times ... */
811 #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = vec_mul(vec_ctf(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT-size)),0), mul);
812 #define EXTRACT_SAMPLE_SIMD_0(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-0));
813 #define EXTRACT_SAMPLE_SIMD_8(srce, var) var = vec_sra(vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(15)), vec_splat_u32(BITSHIFT+16-15-8));
814 #define EXTRACT_SAMPLE_SIMD_16(srce, var) var = vec_sra(vec_ld(0, (vector signed int const *)(srce)), vec_splat_u32(BITSHIFT+16-16));
815 #define PUT_SAMPLE_SIMD_W(dste, v1, v2)  vec_st(vec_packs(v1, v2), 0, dste);
816 #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4)  vec_st(vec_add(vec_packs((vector signed short)vec_packs(v1, v2), (vector signed short)vec_packs(v3, v4)), vec_set1_8(128)), 0, dste);
817 #define PUT_SAMPLE_SIMD_F(dste, v1)  vec_st(v1, 0, dste);
818 #define LOAD_PS1_SIMD(ptr) vec_load_ps1(ptr)
819
820 #elif defined HAVE_SSE2
821
822 #include <emmintrin.h>
823
824 /* SSE2 helper function */
825
826 static __inline __m128i mm_hiqq(const __m128i a) {
827    return _mm_srli_si128(a, 8); /* get the 64bit upper part. new 64bit upper is undefined (zeroed is fine). */
828 }
829
830 /* 128-bit mixing macros */
831 #define EXTRACT_SAMPLE_SIMD(srce, var, size) var = _mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT+16-size);
832 #define EXTRACT_SAMPLE_SIMD_F(srce, var, size, mul) var = _mm_mul_ps(_mm_cvtepi32_ps(_mm_srai_epi32(_mm_load_si128((__m128i const *)(srce)), BITSHIFT-size)), mul);
833 #define EXTRACT_SAMPLE_SIMD_0(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 0)
834 #define EXTRACT_SAMPLE_SIMD_8(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 8)
835 #define EXTRACT_SAMPLE_SIMD_16(srce, var) EXTRACT_SAMPLE_SIMD(srce, var, 16)
836 #define PUT_SAMPLE_SIMD_W(dste, v1, v2)  _mm_store_si128((__m128i*)(dste), _mm_packs_epi32(v1, v2));
837 #define PUT_SAMPLE_SIMD_B(dste, v1, v2, v3, v4)  _mm_store_si128((__m128i*)(dste), _mm_add_epi8(_mm_packs_epi16(_mm_packs_epi32(v1, v2), _mm_packs_epi32(v3, v4)), _mm_set1_epi8(128)));
838 #define PUT_SAMPLE_SIMD_F(dste, v1)  _mm_store_ps((float*)(dste), v1);
839 #define LOAD_PS1_SIMD(ptr) _mm_load_ps1(ptr)
840 #define simd_m128i __m128i
841 #define simd_m128 __m128
842
843 #endif
844
845 #if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
846 /* MikMod_amalloc() returns a 16 byte aligned zero-filled
847    memory in SIMD-enabled builds.
848  - the returned memory can be freed with MikMod_afree()
849  - the returned memory CAN NOT be realloc()'ed safely.  */
850 #ifdef __cplusplus
851 extern "C" {
852 #endif
853 void* MikMod_amalloc(size_t);
854 void MikMod_afree(void *);  /* frees if ptr != NULL */
855 #ifdef __cplusplus
856 }
857 #endif
858
859 #else /* NO SIMD */
860 #define MikMod_amalloc MikMod_malloc
861 #define MikMod_afree MikMod_free
862 #endif
863
864 #endif /* _MIKMOD_INTERNALS_H */
865
866 /* ex:set ts=4: */