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