OSDN Git Service

[portaudio] Import pa_stable_v190700_20210406
[timidity41/timidity41.git] / libunimod / mlutil.c
1 /*      MikMod sound library
2         (c) 1998, 1999 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   $Id$
24
25   Utility functions for the module loader
26
27 ==============================================================================*/
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_MEMORY_H
34 #include <memory.h>
35 #endif
36
37 #include <string.h>
38 #include "unimod_priv.h"
39 #include "common.h"
40 //extern void *safe_realloc(void *old_ptr, size_t new_size);
41
42 SBYTE  remap[UF_MAXCHAN];           /* for removing empty channels */
43 UBYTE* poslookup=NULL;      /* lookup table for pattern jumps after blank
44                                pattern removal */
45 UBYTE  poslookupcnt;
46 UWORD* origpositions=NULL;
47
48 BOOL   filters;             /* resonant filters in use */
49 UBYTE  activemacro;         /* active midi macro number for Sxx,xx<80h */
50 UBYTE  filtermacros[UF_MAXMACRO];    /* midi macros settings */
51 FILTER filtersettings[UF_MAXFILTER]; /* computed filter settings */
52
53 /* tracker identifiers */
54 const CHAR *STM_Signatures[STM_NTRACKERS] =
55 {
56   "!Scream!",
57   "BMOD2STM",
58   "WUZAMOD!"
59 };
60 const CHAR *STM_Version[STM_NTRACKERS] =
61 {
62   "Screamtracker 2",
63   "Converted by MOD2STM (STM format)",
64   "Wuzamod (STM format)"
65 };
66
67
68 /*========== Linear periods stuff */
69
70
71 /* Triton's linear periods to frequency translation table (for XM modules) */
72 static const ULONG lintab[768] =
73 {
74   535232, 534749, 534266, 533784, 533303, 532822, 532341, 531861,
75   531381, 530902, 530423, 529944, 529466, 528988, 528511, 528034,
76   527558, 527082, 526607, 526131, 525657, 525183, 524709, 524236,
77   523763, 523290, 522818, 522346, 521875, 521404, 520934, 520464,
78   519994, 519525, 519057, 518588, 518121, 517653, 517186, 516720,
79   516253, 515788, 515322, 514858, 514393, 513929, 513465, 513002,
80   512539, 512077, 511615, 511154, 510692, 510232, 509771, 509312,
81   508852, 508393, 507934, 507476, 507018, 506561, 506104, 505647,
82   505191, 504735, 504280, 503825, 503371, 502917, 502463, 502010,
83   501557, 501104, 500652, 500201, 499749, 499298, 498848, 498398,
84   497948, 497499, 497050, 496602, 496154, 495706, 495259, 494812,
85   494366, 493920, 493474, 493029, 492585, 492140, 491696, 491253,
86   490809, 490367, 489924, 489482, 489041, 488600, 488159, 487718,
87   487278, 486839, 486400, 485961, 485522, 485084, 484647, 484210,
88   483773, 483336, 482900, 482465, 482029, 481595, 481160, 480726,
89   480292, 479859, 479426, 478994, 478562, 478130, 477699, 477268,
90   476837, 476407, 475977, 475548, 475119, 474690, 474262, 473834,
91   473407, 472979, 472553, 472126, 471701, 471275, 470850, 470425,
92   470001, 469577, 469153, 468730, 468307, 467884, 467462, 467041,
93   466619, 466198, 465778, 465358, 464938, 464518, 464099, 463681,
94   463262, 462844, 462427, 462010, 461593, 461177, 460760, 460345,
95   459930, 459515, 459100, 458686, 458272, 457859, 457446, 457033,
96   456621, 456209, 455797, 455386, 454975, 454565, 454155, 453745,
97   453336, 452927, 452518, 452110, 451702, 451294, 450887, 450481,
98   450074, 449668, 449262, 448857, 448452, 448048, 447644, 447240,
99   446836, 446433, 446030, 445628, 445226, 444824, 444423, 444022,
100   443622, 443221, 442821, 442422, 442023, 441624, 441226, 440828,
101   440430, 440033, 439636, 439239, 438843, 438447, 438051, 437656,
102   437261, 436867, 436473, 436079, 435686, 435293, 434900, 434508,
103   434116, 433724, 433333, 432942, 432551, 432161, 431771, 431382,
104   430992, 430604, 430215, 429827, 429439, 429052, 428665, 428278,
105   427892, 427506, 427120, 426735, 426350, 425965, 425581, 425197,
106   424813, 424430, 424047, 423665, 423283, 422901, 422519, 422138,
107   421757, 421377, 420997, 420617, 420237, 419858, 419479, 419101,
108   418723, 418345, 417968, 417591, 417214, 416838, 416462, 416086,
109   415711, 415336, 414961, 414586, 414212, 413839, 413465, 413092,
110   412720, 412347, 411975, 411604, 411232, 410862, 410491, 410121,
111   409751, 409381, 409012, 408643, 408274, 407906, 407538, 407170,
112   406803, 406436, 406069, 405703, 405337, 404971, 404606, 404241,
113   403876, 403512, 403148, 402784, 402421, 402058, 401695, 401333,
114   400970, 400609, 400247, 399886, 399525, 399165, 398805, 398445,
115   398086, 397727, 397368, 397009, 396651, 396293, 395936, 395579,
116   395222, 394865, 394509, 394153, 393798, 393442, 393087, 392733,
117   392378, 392024, 391671, 391317, 390964, 390612, 390259, 389907,
118   389556, 389204, 388853, 388502, 388152, 387802, 387452, 387102,
119   386753, 386404, 386056, 385707, 385359, 385012, 384664, 384317,
120   383971, 383624, 383278, 382932, 382587, 382242, 381897, 381552,
121   381208, 380864, 380521, 380177, 379834, 379492, 379149, 378807,
122   378466, 378124, 377783, 377442, 377102, 376762, 376422, 376082,
123   375743, 375404, 375065, 374727, 374389, 374051, 373714, 373377,
124   373040, 372703, 372367, 372031, 371695, 371360, 371025, 370690,
125   370356, 370022, 369688, 369355, 369021, 368688, 368356, 368023,
126   367691, 367360, 367028, 366697, 366366, 366036, 365706, 365376,
127   365046, 364717, 364388, 364059, 363731, 363403, 363075, 362747,
128   362420, 362093, 361766, 361440, 361114, 360788, 360463, 360137,
129   359813, 359488, 359164, 358840, 358516, 358193, 357869, 357547,
130   357224, 356902, 356580, 356258, 355937, 355616, 355295, 354974,
131   354654, 354334, 354014, 353695, 353376, 353057, 352739, 352420,
132   352103, 351785, 351468, 351150, 350834, 350517, 350201, 349885,
133   349569, 349254, 348939, 348624, 348310, 347995, 347682, 347368,
134   347055, 346741, 346429, 346116, 345804, 345492, 345180, 344869,
135   344558, 344247, 343936, 343626, 343316, 343006, 342697, 342388,
136   342079, 341770, 341462, 341154, 340846, 340539, 340231, 339924,
137   339618, 339311, 339005, 338700, 338394, 338089, 337784, 337479,
138   337175, 336870, 336566, 336263, 335959, 335656, 335354, 335051,
139   334749, 334447, 334145, 333844, 333542, 333242, 332941, 332641,
140   332341, 332041, 331741, 331442, 331143, 330844, 330546, 330247,
141   329950, 329652, 329355, 329057, 328761, 328464, 328168, 327872,
142   327576, 327280, 326985, 326690, 326395, 326101, 325807, 325513,
143   325219, 324926, 324633, 324340, 324047, 323755, 323463, 323171,
144   322879, 322588, 322297, 322006, 321716, 321426, 321136, 320846,
145   320557, 320267, 319978, 319690, 319401, 319113, 318825, 318538,
146   318250, 317963, 317676, 317390, 317103, 316817, 316532, 316246,
147   315961, 315676, 315391, 315106, 314822, 314538, 314254, 313971,
148   313688, 313405, 313122, 312839, 312557, 312275, 311994, 311712,
149   311431, 311150, 310869, 310589, 310309, 310029, 309749, 309470,
150   309190, 308911, 308633, 308354, 308076, 307798, 307521, 307243,
151   306966, 306689, 306412, 306136, 305860, 305584, 305308, 305033,
152   304758, 304483, 304208, 303934, 303659, 303385, 303112, 302838,
153   302565, 302292, 302019, 301747, 301475, 301203, 300931, 300660,
154   300388, 300117, 299847, 299576, 299306, 299036, 298766, 298497,
155   298227, 297958, 297689, 297421, 297153, 296884, 296617, 296349,
156   296082, 295815, 295548, 295281, 295015, 294749, 294483, 294217,
157   293952, 293686, 293421, 293157, 292892, 292628, 292364, 292100,
158   291837, 291574, 291311, 291048, 290785, 290523, 290261, 289999,
159   289737, 289476, 289215, 288954, 288693, 288433, 288173, 287913,
160   287653, 287393, 287134, 286875, 286616, 286358, 286099, 285841,
161   285583, 285326, 285068, 284811, 284554, 284298, 284041, 283785,
162   283529, 283273, 283017, 282762, 282507, 282252, 281998, 281743,
163   281489, 281235, 280981, 280728, 280475, 280222, 279969, 279716,
164   279464, 279212, 278960, 278708, 278457, 278206, 277955, 277704,
165   277453, 277203, 276953, 276703, 276453, 276204, 275955, 275706,
166   275457, 275209, 274960, 274712, 274465, 274217, 273970, 273722,
167   273476, 273229, 272982, 272736, 272490, 272244, 271999, 271753,
168   271508, 271263, 271018, 270774, 270530, 270286, 270042, 269798,
169   269555, 269312, 269069, 268826, 268583, 268341, 268099, 267857
170 };
171
172 static const UWORD oldperiods[OCTAVE * 2] =
173 {
174   1712 * 16, 1664 * 16, 1616 * 16, 1570 * 16, 1524 * 16, 1480 * 16,
175   1438 * 16, 1396 * 16, 1356 * 16, 1318 * 16, 1280 * 16, 1244 * 16,
176   1208 * 16, 1174 * 16, 1140 * 16, 1108 * 16, 1076 * 16, 1046 * 16,
177   1016 * 16, 988 * 16, 960 * 16, 932 * 16, 906 * 16, 880 * 16
178 };
179
180 #define LOGFAC 2*16
181 static const UWORD logtab[104] =
182 {
183   LOGFAC * 907, LOGFAC * 900, LOGFAC * 894, LOGFAC * 887,
184   LOGFAC * 881, LOGFAC * 875, LOGFAC * 868, LOGFAC * 862,
185   LOGFAC * 856, LOGFAC * 850, LOGFAC * 844, LOGFAC * 838,
186   LOGFAC * 832, LOGFAC * 826, LOGFAC * 820, LOGFAC * 814,
187   LOGFAC * 808, LOGFAC * 802, LOGFAC * 796, LOGFAC * 791,
188   LOGFAC * 785, LOGFAC * 779, LOGFAC * 774, LOGFAC * 768,
189   LOGFAC * 762, LOGFAC * 757, LOGFAC * 752, LOGFAC * 746,
190   LOGFAC * 741, LOGFAC * 736, LOGFAC * 730, LOGFAC * 725,
191   LOGFAC * 720, LOGFAC * 715, LOGFAC * 709, LOGFAC * 704,
192   LOGFAC * 699, LOGFAC * 694, LOGFAC * 689, LOGFAC * 684,
193   LOGFAC * 678, LOGFAC * 675, LOGFAC * 670, LOGFAC * 665,
194   LOGFAC * 660, LOGFAC * 655, LOGFAC * 651, LOGFAC * 646,
195   LOGFAC * 640, LOGFAC * 636, LOGFAC * 632, LOGFAC * 628,
196   LOGFAC * 623, LOGFAC * 619, LOGFAC * 614, LOGFAC * 610,
197   LOGFAC * 604, LOGFAC * 601, LOGFAC * 597, LOGFAC * 592,
198   LOGFAC * 588, LOGFAC * 584, LOGFAC * 580, LOGFAC * 575,
199   LOGFAC * 570, LOGFAC * 567, LOGFAC * 563, LOGFAC * 559,
200   LOGFAC * 555, LOGFAC * 551, LOGFAC * 547, LOGFAC * 543,
201   LOGFAC * 538, LOGFAC * 535, LOGFAC * 532, LOGFAC * 528,
202   LOGFAC * 524, LOGFAC * 520, LOGFAC * 516, LOGFAC * 513,
203   LOGFAC * 508, LOGFAC * 505, LOGFAC * 502, LOGFAC * 498,
204   LOGFAC * 494, LOGFAC * 491, LOGFAC * 487, LOGFAC * 484,
205   LOGFAC * 480, LOGFAC * 477, LOGFAC * 474, LOGFAC * 470,
206   LOGFAC * 467, LOGFAC * 463, LOGFAC * 460, LOGFAC * 457,
207   LOGFAC * 453, LOGFAC * 450, LOGFAC * 447, LOGFAC * 443,
208   LOGFAC * 440, LOGFAC * 437, LOGFAC * 434, LOGFAC * 431
209 };
210
211
212 int*   noteindex=NULL;      /* remap value for linear period modules */
213 static int noteindexcount=0;
214
215 int *AllocLinear(void)
216 {
217         if(of.numsmp>noteindexcount) {
218                 noteindexcount=of.numsmp;
219                 noteindex=safe_realloc(noteindex,noteindexcount*sizeof(int));
220         }
221         return noteindex;
222 }
223
224 void FreeLinear(void)
225 {
226         if(noteindex) {
227                 free(noteindex);
228                 noteindex=NULL;
229         }
230         noteindexcount=0;
231 }
232
233 static SWORD 
234 Interpolate (SWORD p, SWORD p1, SWORD p2, SWORD v1, SWORD v2)
235 {
236   if ((p1 == p2) || (p == p1))
237     return v1;
238   return v1 + ((SLONG) ((p - p1) * (v2 - v1)) / (p2 - p1));
239 }
240
241
242 UWORD 
243 getlinearperiod (UWORD note, SLONG fine)
244 {
245   SLONG t;
246
247   t = (20L * OCTAVE + 2 - note) * 32L - (fine >> 1);
248   return (UWORD)t;
249 }
250
251
252 /* XM linear period to MOD period conversion */
253 ULONG getfrequency (UWORD flags, ULONG period)
254 {
255   if (flags & UF_LINEAR)
256     return lintab[period % 768] >> (period / 768);
257   else
258     return (8363L * 1712L) / (period ? period : 1);
259 }
260
261 UWORD getlogperiod (UWORD note, ULONG fine)
262 {
263   UWORD n, o;
264   UWORD p1, p2;
265   ULONG i;
266
267   n = note % (2 * OCTAVE);
268   o = note / (2 * OCTAVE);
269   i = (n << 2) + (fine >> 4);   /* n*8 + fine/16 */
270
271   p1 = logtab[i];
272   p2 = logtab[i + 1];
273
274   return (Interpolate (fine >> 4, 0, 15, p1, p2) >> o);
275 }
276
277 UWORD getoldperiod (UWORD note, ULONG speed)
278 {
279   UWORD n, o;
280
281   if (!speed)
282     {
283 #ifdef MIKMOD_DEBUG
284       fprintf (stderr, "\rmplayer: getoldperiod() called with note=%d, speed=0 !\n", note);
285 #endif
286       return 4242;              /* <- prevent divide overflow.. (42 hehe) */
287     }
288
289   n = note % (2 * OCTAVE);
290   o = note / (2 * OCTAVE);
291   return ((8363L * (ULONG) oldperiods[n]) >> o) / speed;
292 }
293
294 int speed_to_finetune(ULONG speed,int sample)
295 {
296     int ctmp=0,tmp,note=1,finetune=0;
297
298     speed>>=1;
299     while((tmp=getfrequency(of.flags,getlinearperiod(note<<1,0)))<speed) {
300         ctmp=tmp;
301         note++;
302     }
303
304     if(tmp!=speed) {
305         if((tmp-speed)<(speed-ctmp))
306             while(tmp>speed)
307                 tmp=getfrequency(of.flags,getlinearperiod(note<<1,--finetune));
308         else {
309             note--;
310             while(ctmp<speed)
311                 ctmp=getfrequency(of.flags,getlinearperiod(note<<1,++finetune));
312         }
313     }
314
315     noteindex[sample]=note-4*OCTAVE;
316     return finetune;
317 }
318
319 /* XM linear period to MOD period conversion */
320 ULONG getAmigaPeriod (UWORD flags, ULONG period)
321 {
322   if (flags & UF_LINEAR)
323     {
324       period = lintab[period % 768] >> (period / 768);
325       if (period < 1) period = 1;
326       period = (8363L * 1712L) / period;
327     }
328
329   return (period);
330 }
331
332
333 /*========== Order stuff */
334
335 /* handles S3M and IT orders */
336 void S3MIT_CreateOrders(BOOL curious)
337 {
338         int t;
339
340         of.numpos = 0;
341         memset(of.positions,0,poslookupcnt*sizeof(UWORD));
342         memset(poslookup,-1,256);
343         for(t=0;t<poslookupcnt;t++) {
344                 of.positions[of.numpos]=origpositions[t];
345                 poslookup[t]=of.numpos; /* bug fix for freaky S3Ms / ITs */
346                 if(origpositions[t]<254) of.numpos++;
347                 else
348                         /* end of song special order */
349                         if((origpositions[t]==255)&&(!(curious--))) break;
350         }
351 }
352
353 /*========== Effect stuff */
354
355 /* handles S3M and IT effects */
356 void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,BOOL oldeffect)
357 {
358         UBYTE lo;
359
360         lo=inf&0xf;
361         /* hi=inf>>4; */
362
363         /* process S3M / IT specific command structure */
364
365         if(cmd!=255) {
366                 switch(cmd) {
367                         case 1: /* Axx set speed to xx */
368                                 UniEffect(UNI_S3MEFFECTA,inf);
369                                 break;
370                         case 2: /* Bxx position jump */
371                                 if (inf<poslookupcnt) {
372                                         /* switch to curious mode if necessary, for example
373                                            sympex.it, deep joy.it */
374                                         if(((SBYTE)poslookup[inf]<0)&&(origpositions[inf]!=255))
375                                                 S3MIT_CreateOrders(1);
376
377                                         if(!((SBYTE)poslookup[inf]<0))
378                                                 UniPTEffect(0xb,poslookup[inf]);
379                                 }
380                                 break;
381                         case 3: /* Cxx patternbreak to row xx */
382                                 if(oldeffect==1)
383                                         UniPTEffect(0xd,(inf>>4)*10+(inf&0xf));
384                                 else
385                                         UniPTEffect(0xd,inf);
386                                 break;
387                         case 4: /* Dxy volumeslide */
388                                 UniEffect(UNI_S3MEFFECTD,inf);
389                                 break;
390                         case 5: /* Exy toneslide down */
391                                 UniEffect(UNI_S3MEFFECTE,inf);
392                                 break;
393                         case 6: /* Fxy toneslide up */
394                                 UniEffect(UNI_S3MEFFECTF,inf);
395                                 break;
396                         case 7: /* Gxx Tone portamento, speed xx */
397                                 UniEffect(UNI_ITEFFECTG,inf);
398                                 break;
399                         case 8: /* Hxy vibrato */
400                                 if(oldeffect&1)
401                                         UniPTEffect(0x4,inf);
402                                 else
403                                         UniEffect(UNI_ITEFFECTH,inf);
404                                 break;
405                         case 9: /* Ixy tremor, ontime x, offtime y */
406                                 if(oldeffect&1)
407                                         UniEffect(UNI_S3MEFFECTI,inf);
408                                 else                     
409                                         UniEffect(UNI_ITEFFECTI,inf);
410                                 break;
411                         case 0xa: /* Jxy arpeggio */
412                                 UniPTEffect(0x0,inf);
413                                 break;
414                         case 0xb: /* Kxy Dual command H00 & Dxy */
415                                 if(oldeffect&1)
416                                         UniPTEffect(0x4,0);    
417                                 else
418                                         UniEffect(UNI_ITEFFECTH,0);
419                                 UniEffect(UNI_S3MEFFECTD,inf);
420                                 break;
421                         case 0xc: /* Lxy Dual command G00 & Dxy */
422                                 if(oldeffect&1)
423                                         UniPTEffect(0x3,0);
424                                 else
425                                         UniEffect(UNI_ITEFFECTG,0);
426                                 UniEffect(UNI_S3MEFFECTD,inf);
427                                 break;
428                         case 0xd: /* Mxx Set Channel Volume */
429                                 UniEffect(UNI_ITEFFECTM,inf);
430                                 break;       
431                         case 0xe: /* Nxy Slide Channel Volume */
432                                 UniEffect(UNI_ITEFFECTN,inf);
433                                 break;
434                         case 0xf: /* Oxx set sampleoffset xx00h */
435                                 UniPTEffect(0x9,inf);
436                                 break;
437                         case 0x10: /* Pxy Slide Panning Commands */
438                                 UniEffect(UNI_ITEFFECTP,inf);
439                                 break;
440                         case 0x11: /* Qxy Retrig (+volumeslide) */
441                                 UniWriteByte(UNI_S3MEFFECTQ);
442                                 if(inf && !lo && !(oldeffect&1))
443                                         UniWriteByte(1);
444                                 else
445                                         UniWriteByte(inf); 
446                                 break;
447                         case 0x12: /* Rxy tremolo speed x, depth y */
448                                 UniEffect(UNI_S3MEFFECTR,inf);
449                                 break;
450                         case 0x13: /* Sxx special commands */
451                                 if (inf>=0xf0) {
452                                         /* change resonant filter settings if necessary */
453                                         if((filters)&&((inf&0xf)!=activemacro)) {
454                                                 activemacro=inf&0xf;
455                                                 for(inf=0;inf<0x80;inf++)
456                                                         filtersettings[inf].filter=filtermacros[activemacro];
457                                         }
458                                 } else
459                                         UniEffect(UNI_ITEFFECTS0,inf);
460                                 break;
461                         case 0x14: /* Txx tempo */
462                                 if(inf>=0x20)
463                                         UniEffect(UNI_S3MEFFECTT,inf);
464                                 else {
465                                         if(!(oldeffect&1))
466                                                 /* IT Tempo slide */
467                                                 UniEffect(UNI_ITEFFECTT,inf);
468                                 }
469                                 break;
470                         case 0x15: /* Uxy Fine Vibrato speed x, depth y */
471                                 if(oldeffect&1)
472                                         UniEffect(UNI_S3MEFFECTU,inf);
473                                 else
474                                         UniEffect(UNI_ITEFFECTU,inf);
475                                 break;
476                         case 0x16: /* Vxx Set Global Volume */
477                                 UniEffect(UNI_XMEFFECTG,inf);
478                                 break;
479                         case 0x17: /* Wxy Global Volume Slide */
480                                 UniEffect(UNI_ITEFFECTW,inf);
481                                 break;
482                         case 0x18: /* Xxx amiga command 8xx */
483                                 if(oldeffect&1) {
484                                         if(inf>128)
485                                                 UniEffect(UNI_ITEFFECTS0,0x91); /* surround */
486                                         else
487                                                 UniPTEffect(0x8,(inf==128)?255:(inf<<1));
488                                 } else
489                                         UniPTEffect(0x8,inf);
490                                 break;
491                         case 0x19: /* Yxy Panbrello  speed x, depth y */
492                                 UniEffect(UNI_ITEFFECTY,inf);
493                                 break;
494                         case 0x1a: /* Zxx midi/resonant filters */
495                                 if(filtersettings[inf].filter) {
496                                         UniWriteByte(UNI_ITEFFECTZ);
497                                         UniWriteByte(filtersettings[inf].filter);
498                                         UniWriteByte(filtersettings[inf].inf);
499                                 }
500                                 break;
501                 }
502         }
503 }
504
505 /*========== Unitrk stuff */
506
507 /* Generic effect writing routine */
508 void UniEffect(UWORD eff,UWORD dat)
509 {
510         if((!eff)||(eff>=UNI_LAST)) return;
511
512         UniWriteByte(eff);
513         if(unioperands[eff]==2)
514                 UniWriteWord(dat);
515         else
516                 UniWriteByte(dat);
517 }
518
519 /*  Appends UNI_PTEFFECTX opcode to the unitrk stream. */
520 void UniPTEffect(UBYTE eff, UBYTE dat)
521 {
522 #ifdef MIKMOD_DEBUG
523         if (eff>=0x10)
524                 fprintf(stderr,"UniPTEffect called with incorrect eff value %d\n",eff);
525         else
526 #endif
527         if((eff)||(dat)||(of.flags & UF_ARPMEM)) UniEffect(UNI_PTEFFECT0+eff,dat);
528 }
529
530 /* Appends UNI_VOLEFFECT + effect/dat to unistream. */
531 void UniVolEffect(UWORD eff,UBYTE dat)
532 {
533         if((eff)||(dat)) { /* don't write empty effect */
534                 UniWriteByte(UNI_VOLEFFECTS);
535                 UniWriteByte(eff);UniWriteByte(dat);
536         }
537 }
538
539 /* ex:set ts=4: */