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