1 /* OpenCP Module Player
2 * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3 *
4 * GMDPlay - generic modular module player
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * revision history: (please note changes here)
21 * -nb980510 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
22 * -first release
23 * -kb980717 Tammo Hinrichs <opencp@gmx.net>
24 * -fixed offset command behaviour on offset>samplelength
25 * -doj20020901 Dirk Jagdmann <doj@cubic.org>
26 * -enable/disable pattern looping
27 */
28
29 #include "config.h"
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include "types.h"
34 #include "cpiface/cpiface.h"
35 #include "dev/mcp.h"
36 #include "gmdplay.h"
37 #include "stuff/imsrtns.h"
38
39 #define MAXLCHAN MP_MAXCHANNELS
40 #define MAXPCHAN 32
41
42 struct trackdata
43 {
44 uint8_t num;
45 struct gmdtrack trk;
46 uint8_t selinst;
47 const struct gmdinstrument *instr;
48 const struct gmdsample *samp;
49 uint16_t cursampnum;
50 int16_t vol;
51 int16_t pan;
52 int16_t pany;
53 int16_t panz;
54 uint8_t pansrnd;
55 int32_t pitch;
56 uint8_t nteval;
57 uint8_t notehit;
58 uint8_t volslide;
59 uint8_t pitchslide;
60 uint8_t panslide;
61 uint8_t volfx;
62 uint8_t pitchfx;
63 uint8_t panfx;
64 uint8_t notefx;
65 int16_t delay;
66 uint8_t fx;
67 int16_t volslideval;
68 uint8_t volslides3m;
69 int16_t pitchslideval;
70 uint8_t pitchslides3m;
71 int32_t pitchslidepitch;
72 int16_t pitchslidenteval;
73 int8_t panslideval;
74 uint8_t volvibpos, volvibspd, volvibamp, volvibwave;
75 uint8_t pitchvibpos, pitchvibspd, pitchvibamp, pitchvibwave;
76 uint8_t panvibpos, panvibspd, panvibamp, panvibwave;
77 uint8_t tremval, trempos, tremon, tremlen;
78 uint8_t arpval;
79 uint8_t arppos;
80 uint8_t arpnte[3];
81 uint32_t ofs;
82 uint8_t ofshigh;
83 uint32_t insofs;
84 uint8_t retrig;
85 uint8_t retrigpos;
86 uint8_t cuttick;
87 const uint8_t *delaycmd;
88 int16_t rowvolslval;
89 int8_t rowpanslval;
90 int16_t rowpitchslval;
91 int16_t finalvol;
92 int16_t finalpan;
93 int32_t finalpitch;
94 uint16_t venvpos, penvpos, pchenvpos, vibenvpos;
95 uint32_t venvfrac, penvfrac, pchenvfrac, vibenvfrac;
96 uint32_t vibsweeppos;
97 uint16_t fadevol;
98 uint8_t sustain;
99 uint8_t chanvol;
100 uint8_t lastvolsl;
101 uint8_t lastpitchsl;
102 int8_t glissando;
103 uint_fast32_t newpos;
104 uint_fast32_t newposend;
105 int newdir;
106 int newloop;
107 int newinst;
108 int stopchan;
109 int phys;
110 int mute;
111 };
112
113 static int pchan[MAXPCHAN];
114
115
116 static uint16_t notetab[16]={32768,30929,29193,27554,26008,24548,23170,21870,20643,19484,18390,17358,16384,15464,14596,13777};
117
118 static int16_t sintab[256]=
119 {
120 0, 50, 100, 151, 201, 251, 301, 350,
121 400, 449, 498, 546, 595, 642, 690, 737,
122 784, 830, 876, 921, 965, 1009, 1053, 1096,
123 1138, 1179, 1220, 1260, 1299, 1338, 1375, 1412,
124 1448, 1483, 1517, 1551, 1583, 1615, 1645, 1674,
125 1703, 1730, 1757, 1782, 1806, 1829, 1851, 1872,
126 1892, 1911, 1928, 1945, 1960, 1974, 1987, 1998,
127 2009, 2018, 2026, 2033, 2038, 2042, 2046, 2047,
128 2048
129 /*
130 , 2047, 2046, 2042, 2038, 2033, 2026, 2018,
131 2009, 1998, 1987, 1974, 1960, 1945, 1928, 1911,
132 1892, 1872, 1851, 1829, 1806, 1782, 1757, 1730,
133 1703, 1674, 1645, 1615, 1583, 1551, 1517, 1483,
134 1448, 1412, 1375, 1338, 1299, 1260, 1220, 1179,
135 1138, 1096, 1053, 1009, 965, 921, 876, 830,
136 784, 737, 690, 642, 595, 546, 498, 449,
137 400, 350, 301, 251, 201, 151, 100, 50,
138 0, -50, -100, -151, -201, -251, -301, -350,
139 -400, -449, -498, -546, -595, -642, -690, -737,
140 -784, -830, -876, -921, -965, -1009, -1053, -1096,
141 -1138, -1179, -1220, -1260, -1299, -1338, -1375, -1412,
142 -1448, -1483, -1517, -1551, -1583, -1615, -1645, -1674,
143 -1703, -1730, -1757, -1782, -1806, -1829, -1851, -1872,
144 -1892, -1911, -1928, -1945, -1960, -1974, -1987, -1998,
145 -2009, -2018, -2026, -2033, -2038, -2042, -2046, -2047,
146 -2048, -2047, -2046, -2042, -2038, -2033, -2026, -2018,
147 -2009, -1998, -1987, -1974, -1960, -1945, -1928, -1911,
148 -1892, -1872, -1851, -1829, -1806, -1782, -1757, -1730,
149 -1703, -1674, -1645, -1615, -1583, -1551, -1517, -1483,
150 -1448, -1412, -1375, -1338, -1299, -1260, -1220, -1179,
151 -1138, -1096, -1053, -1009, -965, -921, -876, -830,
152 -784, -737, -690, -642, -595, -546, -498, -449,
153 -400, -350, -301, -251, -201, -151, -100, -50
154 */
155 };
156
157 static uint8_t channels;
158 static uint8_t physchan;
159 static uint8_t currenttick;
160 static uint8_t tempo;
161 static uint16_t currentrow;
162 static uint16_t patternlen;
163 static uint16_t currentpattern;
164 static int lockpattern;
165 static uint16_t patternnum;
166 static uint16_t looppat;
167 static uint16_t endpat;
168 static struct trackdata tdata[MP_MAXCHANNELS];
169 static struct trackdata *tdataend;
170 static struct gmdtrack gtrack;
171 static const struct gmdenvelope *envelopes;
172 static const struct gmdpattern *patterns;
173 static const struct gmdtrack *tracks;
174 static const struct gmdsample *modsamples;
175 static const struct gmdinstrument *instruments;
176 static const struct sampleinfo *sampleinfos;
177 static const uint16_t *orders;
178 static uint16_t instnum;
179 static uint16_t speed;
180 static int modsampnum;
181 static int sampnum;
182 static int envnum;
183 static int16_t brkpat;
184 static int16_t brkrow;
185 static uint8_t newtickmode;
186 static uint8_t processtick;
187 static uint8_t patlooprow[MAXLCHAN];
188 static uint8_t patloopcount[MAXLCHAN];
189 static uint8_t globchan;
190 static uint8_t patdelay;
191 static uint8_t globalvol;
192 static uint8_t globalvolslide[MAXLCHAN];
193 static int8_t globalvolslval[MAXLCHAN];
194 static uint8_t looped;
195 static uint8_t exponential;
196 static uint8_t samiextrawurscht;
197 static uint8_t samisami;
198 static uint8_t gusvol;
199 static uint8_t expopitchenv;
200 static uint8_t donotloopmodule;
201 static uint8_t donotshutup;
202 static int realpos;
203
204 static int (*que)[4]; /* one int is padding */
205 static int querpos;
206 static int quewpos;
207 static int quelen;
208
209 #define HPITCHMIN (6848>>6)
210 #define HPITCHMAX ((int32_t)6848<<6)
211 #define EPITCHMIN -72*256
212 #define EPITCHMAX 96*256
213
readque(void)214 static void readque(void)
215 {
216 int type,val1/*,val2*/;
217 int time=mcpGet(-1, mcpGTimer);
218 while (1)
219 {
220 if (querpos==quewpos)
221 break;
222 if (time<que[querpos][0])
223 break;
224 type=que[querpos][1];
225 val1=que[querpos][2];
226 /* val2=que[querpos][3] */;
227 querpos=(querpos+1)%quelen;
228 if (type==-1)
229 realpos=val1;
230 }
231 }
232
trackmoveto(struct gmdtrack * t,uint8_t row)233 static void trackmoveto(struct gmdtrack *t, uint8_t row)
234 {
235 while (1)
236 {
237 if (t->ptr>=t->end)
238 break;
239 if (t->ptr[0]>=row)
240 break;
241 t->ptr+=t->ptr[1]+2;
242 }
243 }
244
LoadPattern(uint16_t p,uint8_t r)245 static void LoadPattern(uint16_t p, uint8_t r)
246 {
247 const struct gmdpattern *pat=&patterns[orders[p]];
248 struct trackdata *td;
249
250 patternlen=pat->patlen;
251 if (r>=patternlen)
252 r=0;
253 currenttick=0;
254 currentrow=r;
255 currentpattern=p;
256
257 gtrack=tracks[pat->gtrack];
258 trackmoveto(>rack, r);
259 for (td=tdata; td<tdataend; td++)
260 {
261 td->trk=tracks[pat->tracks[td->num]];
262 trackmoveto(&td->trk, r);
263 }
264 }
265
checkvol(int16_t v)266 static inline unsigned char checkvol(int16_t v)
267 {
268 return (v<0)?0:(v>255)?255:v;
269 }
270
checkpan(int16_t p)271 static inline unsigned char checkpan(int16_t p)
272 {
273 return (p<0)?0:(p>=255)?255:p;
274 }
275
checkpitchh(int32_t pitch)276 static inline signed long checkpitchh(int32_t pitch)
277 {
278 return (pitch<HPITCHMIN)?HPITCHMIN:(pitch>HPITCHMAX)?HPITCHMAX:pitch;
279 }
280
checkpitche(int32_t pitch)281 static inline signed long checkpitche(int32_t pitch)
282 {
283 return (pitch<EPITCHMIN)?EPITCHMIN:(pitch>EPITCHMAX)?EPITCHMAX:pitch;
284 }
285
checkpitch(int32_t pitch)286 static inline signed long checkpitch(int32_t pitch)
287 {
288 if (exponential)
289 return checkpitche(pitch);
290 else
291 return checkpitchh(pitch);
292 }
293
PlayNote(struct trackdata * t,const uint8_t * dat)294 static uint8_t PlayNote(struct trackdata *t, const uint8_t *dat)
295 {
296 const uint8_t *od=dat;
297 int16_t ins=-1;
298 int16_t nte=-1;
299 int16_t portante=-1;
300 int16_t vol=t->vol;
301 int16_t pan=t->pan;
302 int16_t delay=-1;
303 uint8_t opt=*dat++;
304
305 if (opt&cmdPlayIns)
306 ins=*dat++;
307 if (opt&cmdPlayNte)
308 {
309 if (*dat&0x80)
310 portante=*dat++&~0x80;
311 else
312 nte=*dat++;
313 }
314 if (opt&cmdPlayVol)
315 vol=*dat++;
316 if (opt&cmdPlayPan)
317 {
318 pan=*dat++;
319 t->pansrnd=0;
320 }
321 if (opt&cmdPlayDelay)
322 delay=*dat++;
323
324 if (delay!=-1)
325 {
326 t->fx=fxDelay;
327 t->delaycmd=od;
328 t->delay=delay;
329 }
330
331 if (((delay!=currenttick)||!processtick)&&((delay!=-1)||patdelay))
332 return dat-od;
333
334 if (ins!=-1)
335 {
336 t->selinst=ins;
337 if (samiextrawurscht)
338 t->insofs=0;
339 if (t->sustain||(nte!=-1)||(portante!=-1))
340 {
341 t->venvpos=t->penvpos=t->pchenvpos=t->vibenvpos=0;
342 t->venvfrac=t->penvfrac=t->pchenvfrac=t->vibenvfrac=0;
343 t->fadevol=0x8000;
344 t->sustain=1;
345 t->vibsweeppos=0;
346 }
347 if (&instruments[t->selinst]==t->instr)
348 {
349 } else if (portante!=-1)
350 {
351 if (t->instr&&samiextrawurscht)
352 nte=t->nteval;
353 if (!t->instr)
354 nte=portante;
355 }
356 }
357
358 if (nte!=-1)
359 {
360 if ((t->selinst>=instnum)||(instruments[t->selinst].samples[nte]>=modsampnum)||(modsamples[instruments[t->selinst].samples[nte]].handle>=sampnum))
361 {
362 if (t->phys!=-1)
363 {
364 mcpSet(t->phys, mcpCReset, 0);
365 pchan[t->phys]=-1;
366 t->phys=-1;
367 }
368 t->instr=0;
369 t->samp=0;
370 nte=-1;
371 } else {
372 t->instr=&instruments[t->selinst];
373 t->samp=&modsamples[t->instr->samples[nte]];
374 t->newinst=t->samp->handle;
375 }
376 }
377
378 if ((opt&cmdPlayIns)&&t->instr&&t->samp/*&&((&instruments[t->selinst]==t->instr)||!samiextrawurscht)*/)
379 {
380 if ((t->samp->stdvol!=-1)&&!(opt&cmdPlayVol))
381 vol=t->samp->stdvol;
382 if ((t->samp->stdpan!=-1)&&!(opt&cmdPlayPan))
383 {
384 pan=t->samp->stdpan;
385 t->pansrnd=0;
386 }
387 }
388
389
390 if (nte!=-1)
391 {
392 uint_fast32_t pos=0;
393
394 t->nteval=nte;
395 t->notehit=1;
396 if (exponential)
397 t->pitchslidepitch=t->finalpitch=t->pitch=60*256-(t->nteval<<8)+t->samp->normnote;
398 else
399 t->pitchslidepitch=t->finalpitch=t->pitch=mcpGetFreq6848(60*256+t->samp->normnote-(t->nteval<<8));
400 if (samiextrawurscht&&t->insofs)
401 pos=(t->samp->opt&MP_OFFSETDIV2)?(t->insofs>>1):t->insofs;
402 t->newpos=pos;
403 t->retrigpos=t->trempos=t->arppos=t->pitchvibpos=t->volvibpos=0;
404 }
405
406 if (portante!=-1)
407 {
408 t->nteval=portante;
409 if (t->samp)
410 {
411 if (exponential)
412 t->pitchslidepitch=60*256-(t->nteval<<8)+t->samp->normnote;
413 else
414 t->pitchslidepitch=mcpGetFreq6848(60*256+t->samp->normnote-(t->nteval<<8));
415 }
416 }
417
418 t->vol=t->finalvol=checkvol(vol);
419 t->pan=t->finalpan=checkpan(pan);
420
421 return dat-od;
422 }
423
PlayGCommand(const uint8_t * cmd,uint8_t len)424 static void PlayGCommand(const uint8_t *cmd, uint8_t len)
425 {
426 const uint8_t *cend=cmd+len;
427 while (cmd<cend)
428 {
429 switch (*cmd++)
430 {
431 case cmdTempo:
432 tempo=*cmd;
433 break;
434 case cmdSpeed:
435 speed=*cmd;
436 mcpSet(-1, mcpGSpeed, 256*2*speed/5);
437 break;
438 case cmdFineSpeed:
439 mcpSet(-1, mcpGSpeed, 256*2*(10*speed+*cmd)/50);
440 break;
441 case cmdBreak:
442 if (brkpat==-1)
443 {
444 brkpat=currentpattern+1;
445 if (brkpat==endpat)
446 {
447 brkpat=looppat;
448 looped=1;
449 }
450 }
451 brkrow=*cmd;
452 donotshutup=0;
453 break;
454 case cmdGoto:
455 brkpat=*cmd;
456 if (brkpat<=currentpattern)
457 looped=1;
458 /* brkrow=0; */
459 donotshutup=0;
460 break;
461 case cmdPatLoop:
462 /*
463 if(plLoopPatterns)*/ /*TODO. take this back? */
464 {
465 if (*cmd)
466 if (patloopcount[globchan]++<*cmd)
467 {
468 brkpat=currentpattern;
469 brkrow=patlooprow[globchan];
470 donotshutup=1;
471 } else {
472 patloopcount[globchan]=0;
473 patlooprow[globchan]=currentrow+1;
474 } else
475 patlooprow[globchan]=currentrow;
476 }
477 break;
478 case cmdPatDelay:
479 if (!patdelay&&*cmd)
480 patdelay=*cmd+1;
481 break;
482 case cmdGlobVol:
483 globalvol=*cmd;
484 break;
485 case cmdGlobVolSlide:
486 if (*cmd)
487 globalvolslval[globchan]=*cmd;
488 globalvolslide[globchan]=(globalvolslval[globchan]>0)?fxGVSUp:fxGVSDown;
489 break;
490 case cmdSetChan:
491 globchan=*cmd;
492 break;
493 }
494 cmd++;
495 }
496 }
497
PlayCommand(struct trackdata * t,const uint8_t * cmd,uint8_t len)498 static void PlayCommand(struct trackdata *t, const uint8_t *cmd, uint8_t len)
499 {
500 const uint8_t *cend=cmd+len;
501 while (cmd<cend)
502 {
503 if (*cmd&cmdPlayNote)
504 {
505 cmd+=PlayNote(t, cmd);
506 continue;
507 }
508 switch (*cmd++)
509 {
510 case cmdVolSlideUp:
511 if (*cmd)
512 t->volslideval=*cmd;
513 else
514 t->volslideval=abs(t->volslideval);
515 t->volslide=fxVSUp;
516 t->fx=fxVolSlideUp;
517 t->lastvolsl=0;
518 break;
519 case cmdVolSlideDown:
520 if (*cmd)
521 t->volslideval=-*cmd;
522 else
523 t->volslideval=-abs(t->volslideval);
524 t->volslide=fxVSDown;
525 t->fx=fxVolSlideDown;
526 t->lastvolsl=0;
527 break;
528 case cmdRowVolSlideUp:
529 if (*cmd)
530 t->rowvolslval=*cmd;
531 else
532 t->rowvolslval=abs(t->rowvolslval);
533 t->fx=fxRowVolSlideUp;
534 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
535 t->lastvolsl=1;
536 break;
537 case cmdRowVolSlideDown:
538 if (*cmd)
539 t->rowvolslval=-*cmd;
540 else
541 t->rowvolslval=-abs(t->rowvolslval);
542 t->fx=fxRowVolSlideDown;
543 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
544 t->lastvolsl=1;
545 break;
546 case cmdVolSlideUDMF:
547 t->volslideval=*cmd;
548 t->volslide=fxVSUDMF;
549 t->fx=fxVolSlideUp;
550 break;
551 case cmdVolSlideDDMF:
552 t->volslideval=-*cmd;
553 t->volslide=fxVSDDMF;
554 t->fx=fxVolSlideDown;
555 break;
556 case cmdRowPanSlide:
557 if (*cmd)
558 t->rowpanslval=*cmd;
559 t->pan=t->finalpan=checkpan(t->pan+t->rowpanslval);
560 break;
561 case cmdPanSlide:
562 if (*cmd)
563 t->panslideval=*cmd;
564 t->panslide=(t->panslideval<0)?fxPnSLeft:fxPnSRight;
565 t->fx=(t->panslideval<0)?fxPanSlideLeft:fxPanSlideRight;
566 break;
567 case cmdPanSlideLDMF:
568 t->panslideval=-(uint16_t)*cmd;
569 t->panslide=fxPnSLDMF;
570 t->fx=fxPanSlideLeft;
571 break;
572 case cmdPanSlideRDMF:
573 t->panslideval=*cmd;
574 t->panslide=fxPnSRDMF;
575 t->fx=fxPanSlideRight;
576 break;
577 case cmdPitchSlideUp:
578 if (*cmd)
579 t->pitchslideval=(int16_t)*cmd<<4;
580 else
581 t->pitchslideval=abs(t->pitchslideval);
582 t->pitchslide=fxPSUp;
583 t->fx=fxPitchSlideUp;
584 t->lastpitchsl=0;
585 break;
586 case cmdPitchSlideDown:
587 if (*cmd)
588 t->pitchslideval=-(int16_t)*cmd<<4;
589 else
590 t->pitchslideval=-abs(t->pitchslideval);
591 t->pitchslide=fxPSDown;
592 t->fx=fxPitchSlideDown;
593 t->lastpitchsl=0;
594 break;
595 case cmdRowPitchSlideUp:
596 if (*cmd)
597 t->rowpitchslval=*cmd;
598 t->fx=fxRowPitchSlideUp;
599 t->finalpitch=t->pitch=checkpitch(t->finalpitch-t->rowpitchslval);
600 t->lastpitchsl=1;
601 break;
602 case cmdRowPitchSlideDown:
603 if (*cmd)
604 t->rowpitchslval=*cmd;
605 t->fx=fxRowPitchSlideDown;
606 t->finalpitch=t->pitch=checkpitch(t->finalpitch+t->rowpitchslval);
607 t->lastpitchsl=1;
608 break;
609 case cmdPitchSlideUDMF:
610 t->fx=fxPitchSlideUp;
611 t->pitchslide=fxPSUDMF;
612 t->pitchslideval=*cmd<<4;
613 break;
614 case cmdPitchSlideDDMF:
615 t->fx=fxPitchSlideDown;
616 t->pitchslide=fxPSDDMF;
617 t->pitchslideval=-(int16_t)(*cmd<<4);
618 break;
619 case cmdRowPitchSlideDMF:
620 t->fx=(*cmd&128)?fxRowPitchSlideDown:fxRowPitchSlideUp;
621 t->finalpitch=t->pitch=checkpitch(t->finalpitch-((int8_t)*cmd<<1));
622 break;
623 case cmdPitchSlideToNote:
624 t->pitchslide=fxPSToNote;
625 t->fx=fxPitchSlideToNote;
626 if (*cmd)
627 t->pitchslidenteval=((uint16_t)*cmd)<<4;
628 break;
629 case cmdPitchSlideNDMF:
630 t->fx=fxPitchSlideToNote;
631 t->pitchslide=fxPSNDMF;
632 t->pitchslidenteval=*cmd<<4;
633 break;
634 case cmdVolVibrato:
635 t->volfx=fxVXVibrato;
636 t->fx=fxVolVibrato;
637 if (*cmd&0x0F)
638 t->volvibamp=(*cmd&0x0F)<<2;
639 if (*cmd>>4)
640 t->volvibspd=(*cmd>>4)<<2;
641 break;
642 case cmdVolVibratoSinDMF:
643 case cmdVolVibratoTrgDMF:
644 case cmdVolVibratoRecDMF:
645 t->volfx=fxVXVibrato;
646 t->fx=fxVolVibrato;
647 t->volvibamp=(*cmd&0xF)+1;
648 t->volvibspd=(*cmd>>4)+1;
649 t->volvibwave=0x20+cmd[-1]-cmdVolVibratoSinDMF;
650 break;
651 case cmdVolVibratoSetWave:
652 switch (*cmd)
653 {
654 case 0: case 1: case 2: case 0x10: case 0x11: case 0x12:
655 t->volvibwave=*cmd;
656 break;
657 case 3:
658 t->volvibwave=rand()%3;
659 break;
660 case 0x13:
661 t->volvibwave=rand()%3+0x10;
662 break;
663 }
664 break;
665 case cmdTremor:
666 if (*cmd||samiextrawurscht)
667 t->tremval=*cmd;
668 t->volfx=fxVXTremor;
669 t->fx=fxTremor;
670 t->tremon=(t->tremval>>4)+1;
671 t->tremlen=(t->tremval&0xF)+1+t->tremon;
672 break;
673 case cmdPitchVibrato:
674 t->pitchfx=fxPXVibrato;
675 t->fx=fxPitchVibrato;
676 if (*cmd&0x0F)
677 t->pitchvibamp=(*cmd&0x0F)<<2;
678 if (*cmd>>4)
679 t->pitchvibspd=(*cmd>>4)<<2;
680 break;
681 case cmdPitchVibratoSinDMF:
682 case cmdPitchVibratoTrgDMF:
683 case cmdPitchVibratoRecDMF:
684 t->pitchfx=fxPXVibrato;
685 t->fx=fxPitchVibrato;
686 t->pitchvibamp=(*cmd&0xF)+1;
687 t->pitchvibspd=(*cmd>>4)+1;
688 t->pitchvibwave=0x20+cmd[-1]-cmdPitchVibratoSinDMF;
689 break;
690 case cmdPitchVibratoFine:
691 t->pitchfx=fxPXVibrato;
692 t->fx=fxPitchVibrato;
693 if (*cmd&0x0F)
694 t->pitchvibamp=*cmd&0x0F;
695 if (*cmd>>4)
696 t->pitchvibspd=(*cmd>>4)<<2;
697 break;
698 case cmdPitchVibratoSetSpeed:
699 if (*cmd&0x0F)
700 t->pitchvibspd=*cmd<<2;
701 break;
702 case cmdPitchVibratoSetWave:
703 switch (*cmd)
704 {
705 case 0: case 1: case 2: case 0x10: case 0x11: case 0x12:
706 t->pitchvibwave=*cmd;
707 break;
708 case 3:
709 t->pitchvibwave=rand()%3;
710 break;
711 case 0x13:
712 t->pitchvibwave=rand()%3+0x10;
713 break;
714 }
715 break;
716 case cmdArpeggio:
717 t->pitchfx=fxPXArpeggio;
718 t->fx=fxArpeggio;
719 if (*cmd)
720 t->arpval=*cmd;
721 t->arpnte[0]=0;
722 t->arpnte[1]=t->arpval>>4;
723 t->arpnte[2]=t->arpval&0x0F;
724 break;
725 case cmdPanSurround:
726 t->pansrnd=1;
727 break;
728 case cmdKeyOff:
729 t->sustain=0;
730 break;
731 case cmdSetEnvPos:
732 t->venvpos=t->penvpos=t->pchenvpos=t->vibenvpos=*cmd;
733 if (t->samp->volenv<envnum)
734 if (t->venvpos>envelopes[t->samp->volenv].len)
735 t->venvpos=envelopes[t->samp->volenv].len;
736 if (t->samp->panenv<envnum)
737 if (t->penvpos>envelopes[t->samp->panenv].len)
738 t->penvpos=envelopes[t->samp->panenv].len;
739 if (t->samp->pchenv<envnum)
740 if (t->pchenvpos>envelopes[t->samp->pchenv].len)
741 t->pchenvpos=envelopes[t->samp->pchenv].len;
742 /*
743 if (t.samp->vibenv<envnum)
744 if (t.vibenvpos>envelopes[t.samp->vibenv].len)
745 t.vibenvpos=envelopes[t.samp->vibenv].len;
746 */
747 break;
748 case cmdNoteCut:
749 t->notefx=fxNXNoteCut;
750 t->fx=fxNoteCut;
751 t->cuttick=*cmd;
752 break;
753 case cmdRetrig:
754 if (*cmd)
755 {
756 t->retrig=*cmd;
757 t->retrigpos=0;
758 }
759 t->notefx=fxNXRetrig;
760 t->fx=fxRetrig;
761 break;
762 case cmdOffsetHigh:
763 t->ofshigh=*cmd;
764 break;
765 case cmdOffset:
766 t->fx=fxOffset;
767 if (!samiextrawurscht || t->notehit)
768 {
769 if (*cmd|t->ofshigh)
770 {
771 t->ofs=(*cmd<<8)|(t->ofshigh<<16);
772 t->ofshigh=0;
773 }
774 t->insofs=t->ofs;
775 t->newpos=(t->samp->opt&MP_OFFSETDIV2)?(t->ofs>>1):t->ofs;
776 }
777 break;
778 case cmdOffsetEnd:
779 t->fx=fxOffset;
780 if (*cmd|t->ofshigh)
781 {
782 t->ofs=(*cmd<<8)|(t->ofshigh<<16);
783 t->ofshigh=0;
784 }
785 t->insofs=t->ofs;
786 t->newpos=(t->samp->opt&MP_OFFSETDIV2)?(t->ofs>>1):t->ofs;
787 t->newposend=1;
788 t->newdir=1;
789 break;
790 case cmdPanVibratoSinDMF:
791 t->panfx=fxPnXVibrato;
792 t->fx=fxPanVibrato;
793 t->panvibamp=(*cmd&0xF)+1;
794 t->panvibspd=(*cmd>>4)+1;
795 t->panvibwave=0x20;
796 break;
797 case cmdPanHeight:
798 t->pany=*cmd-0x80;
799 break;
800 case cmdPanDepth:
801 t->panz=*cmd-0x80;
802 break;
803 case cmdChannelVol:
804 t->chanvol=*cmd;
805 break;
806 case cmdSetDir:
807 t->newdir=*cmd;
808 break;
809 case cmdSetLoop:
810 t->newloop=*cmd;
811 break;
812 case cmdSpecial:
813 switch (*cmd)
814 {
815 case cmdContVolSlide:
816 t->volslide=(t->volslideval<0)?fxVSDown:fxVSUp;
817 t->fx=(t->volslideval<0)?fxVolSlideDown:fxVolSlideUp;
818 break;
819 case cmdContRowVolSlide:
820 t->fx=(t->rowvolslval<0)?fxRowVolSlideDown:fxRowVolSlideUp;
821 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
822 break;
823 case cmdContMixVolSlide:
824 if (!t->lastvolsl)
825 {
826 t->volslide=(t->volslideval<0)?fxVSDown:fxVSUp;
827 t->fx=(t->volslideval<0)?fxVolSlideDown:fxVolSlideUp;
828 } else {
829 t->fx=(t->rowvolslval<0)?fxRowVolSlideDown:fxRowVolSlideUp;
830 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
831 }
832 break;
833 case cmdContMixVolSlideUp:
834 if (!t->lastvolsl)
835 {
836 t->volslideval=abs(t->volslideval);
837 t->volslide=fxVSUp;
838 t->fx=fxVolSlideUp;
839 } else {
840 t->rowvolslval=abs(t->rowvolslval);
841 t->fx=fxRowVolSlideUp;
842 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
843 }
844 break;
845 case cmdContMixVolSlideDown:
846 if (!t->lastvolsl)
847 {
848 t->volslideval=-abs(t->volslideval);
849 t->volslide=fxVSDown;
850 t->fx=fxVolSlideDown;
851 } else {
852 t->rowvolslval=-abs(t->rowvolslval);
853 t->fx=fxRowVolSlideDown;
854 t->vol=t->finalvol=checkvol(t->vol+t->rowvolslval);
855 }
856 break;
857 case cmdContMixPitchSlideUp:
858 if (!t->lastpitchsl)
859 {
860 t->pitchslideval=abs(t->pitchslideval);
861 t->pitchslide=fxPSUp;
862 t->fx=fxPitchSlideUp;
863 } else {
864 t->fx=fxRowPitchSlideUp;
865 t->finalpitch=t->pitch=checkpitch(t->finalpitch-t->rowpitchslval);
866 }
867 break;
868 case cmdContMixPitchSlideDown:
869 if (!t->lastpitchsl)
870 {
871 t->pitchslideval=-abs(t->pitchslideval);
872 t->pitchslide=fxPSDown;
873 t->fx=fxPitchSlideDown;
874 } else {
875 t->fx=fxRowPitchSlideDown;
876 t->finalpitch=t->pitch=checkpitch(t->finalpitch+t->rowpitchslval);
877 }
878 break;
879 case cmdGlissOn:
880 t->glissando=1;
881 break;
882 case cmdGlissOff:
883 t->glissando=0;
884 break;
885 }
886 }
887 cmd++;
888 }
889 }
890
DoGCommand(void)891 static void DoGCommand(void)
892 {
893 int i;
894 for (i=0; i<MAXLCHAN; i++)
895 if (globalvolslide[i])
896 if (processtick)
897 globalvol=checkvol(globalvol+globalvolslval[i]);
898 }
899
DoCommand(struct trackdata * t)900 static void DoCommand(struct trackdata *t)
901 {
902 if (t->delay==currenttick)
903 PlayNote(t, t->delaycmd);
904
905 switch (t->volslide)
906 {
907 case 0:
908 break;
909 case fxVSUp: case fxVSDown:
910 if (processtick||samisami)
911 t->vol=t->finalvol=checkvol(t->vol+t->volslideval);
912 break;
913 case fxVSUDMF: case fxVSDDMF:
914 t->vol=t->finalvol=checkvol(t->vol+t->volslideval*(currenttick+1)/tempo-t->volslideval*currenttick/tempo);
915 break;
916 }
917 switch (t->panslide)
918 {
919 case 0:
920 break;
921 case fxPnSLeft: case fxPnSRight:
922 if (processtick)
923 t->pan=t->finalpan=checkpan(t->pan+t->panslideval);
924 break;
925 case fxPnSLDMF: case fxPnSRDMF:
926 t->pan=t->finalpan=checkpan(t->pan+t->panslideval*(currenttick+1)/tempo-t->panslideval*currenttick/tempo);
927 break;
928 }
929 switch (t->pitchslide)
930 {
931 case 0:
932 break;
933 case fxPSUp: case fxPSDown:
934 if (processtick)
935 {
936 if (samiextrawurscht&&((t->pitch-t->pitchslideval)<0))
937 t->stopchan=1;
938 t->finalpitch=t->pitch=checkpitch(t->pitch-t->pitchslideval);
939 }
940 break;
941 case fxPSToNote:
942 if (!t->samp)
943 return;
944 if (processtick)
945 {
946 if (t->pitch<t->pitchslidepitch)
947 {
948 if ((t->pitch+=t->pitchslidenteval)>t->pitchslidepitch)
949 t->pitch=t->pitchslidepitch;
950 } else {
951 if ((t->pitch-=t->pitchslidenteval)<t->pitchslidepitch)
952 t->pitch=t->pitchslidepitch;
953 }
954 t->pitch=checkpitch(t->pitch);
955 }
956 if (t->glissando)
957 if (exponential)
958 t->finalpitch=((t->pitch+0x80-t->samp->normnote)&~0xFF)+t->samp->normnote;
959 else
960 t->finalpitch=mcpGetFreq6848(((mcpGetNote6848(t->pitch)+0x80-t->samp->normnote)&~0xFF)+t->samp->normnote);
961 else
962 t->finalpitch=t->pitch;
963 break;
964 case fxPSUDMF: case fxPSDDMF:
965 t->finalpitch=t->pitch=checkpitch(t->pitch-t->pitchslideval*(currenttick+1)/tempo+t->pitchslideval*currenttick/tempo);
966 break;
967 case fxPSNDMF:
968 {
969 uint16_t delta;
970 delta=t->pitchslidenteval*(currenttick+1)/tempo-t->pitchslidenteval*currenttick/tempo;
971 if (t->pitch<t->pitchslidepitch)
972 {
973 if ((t->pitch+=delta)>t->pitchslidepitch)
974 t->pitch=t->pitchslidepitch;
975 } else {
976 if ((t->pitch-=delta)<t->pitchslidepitch)
977 t->pitch=t->pitchslidepitch;
978 }
979 t->pitch=t->finalpitch=checkpitch(t->pitch);
980 break;
981 }
982 }
983
984 switch (t->volfx)
985 {
986 case fxVXVibrato:
987 switch (t->volvibwave)
988 {
989 case 0:
990 t->finalvol=checkvol(t->vol+((sintab[t->volvibpos]*t->volvibamp)>>9));
991 break;
992 case 1:
993 t->finalvol=checkvol(t->vol+(((128-t->volvibpos)*t->volvibamp/4)>>3));
994 break;
995 case 2:
996 t->finalvol=checkvol(t->vol+t->volvibamp*((t->volvibpos&128)?-4:4));
997 break;
998 case 0x10:
999 t->finalvol=checkvol(t->vol+((sintab[t->volvibpos]*t->volvibamp)>>10));
1000 break;
1001 case 0x11:
1002 t->finalvol=checkvol(t->vol+((((int16_t)t->volvibpos-128)*t->volvibamp/4)>>4));
1003 break;
1004 case 0x12:
1005 t->finalvol=checkvol(t->vol+t->volvibamp*((t->volvibpos&128)?0:2));
1006 break;
1007 }
1008 if (processtick)
1009 t->volvibpos=t->volvibpos+t->volvibspd;
1010 break;
1011 case fxVXTremor:
1012 t->finalvol=(t->trempos<t->tremon)?t->vol:0;
1013 if (processtick||samiextrawurscht)
1014 t->trempos=(t->trempos+1)%t->tremlen;
1015 break;
1016 }
1017
1018 switch (t->pitchfx)
1019 {
1020 case fxPXVibrato:
1021 if (t->pitchvibwave>=0x20)
1022 {
1023 uint8_t vpos=256*(t->pitchvibpos*tempo+currenttick)/(tempo*t->pitchvibspd);
1024 switch (t->pitchvibwave)
1025 {
1026 case 0x20:
1027 t->finalpitch=checkpitch(t->finalpitch-((sintab[vpos]*t->pitchvibamp)>>6));
1028 break;
1029 }
1030 if ((currenttick+1)==tempo)
1031 {
1032 t->pitchvibpos++;
1033 if (t->pitchvibpos==t->pitchvibspd)
1034 t->pitchvibpos=0;
1035 }
1036 break;
1037 }
1038 switch (t->pitchvibwave)
1039 {
1040 case 0:
1041 t->finalpitch=checkpitch(t->finalpitch+((sintab[t->pitchvibpos]*t->pitchvibamp)>>8));
1042 break;
1043 case 1:
1044 t->finalpitch=checkpitch(t->finalpitch-(128-t->pitchvibpos)*t->pitchvibamp/16);
1045 break;
1046 case 2:
1047 t->finalpitch=checkpitch(t->finalpitch-t->pitchvibamp*((t->pitchvibpos&128)?8:-8));
1048 break;
1049 case 0x10:
1050 t->finalpitch=checkpitch(t->finalpitch+((sintab[t->pitchvibpos]*t->pitchvibamp)>>8));
1051 break;
1052 case 0x11:
1053 t->finalpitch=checkpitch(t->finalpitch+((int16_t)t->pitchvibpos-128)*t->pitchvibamp/16);
1054 break;
1055 case 0x12:
1056 t->finalpitch=checkpitch(t->finalpitch+t->pitchvibamp*((t->pitchvibpos&128)?0:8));
1057 break;
1058 }
1059 if (processtick)
1060 t->pitchvibpos=t->pitchvibpos+t->pitchvibspd;
1061 break;
1062 case fxPXArpeggio:
1063 if (exponential)
1064 t->finalpitch=checkpitch(t->finalpitch-t->arpnte[t->arppos]*256);
1065 else
1066 t->finalpitch=checkpitch(t->finalpitch*notetab[t->arpnte[t->arppos]]/32768);
1067 t->arppos=(t->arppos+1)%3;
1068 break;
1069 }
1070
1071 switch (t->notefx)
1072 {
1073 case fxNXNoteCut:
1074 if (currenttick==t->cuttick)
1075 t->vol=t->finalvol=0;
1076 break;
1077 case fxNXRetrig:
1078 if (t->retrigpos==(t->retrig&0x0F))
1079 {
1080 t->retrigpos=0;
1081 t->newpos=0;
1082 switch (t->retrig>>4)
1083 {
1084 case 1: case 2: case 3: case 4: case 5:
1085 t->vol=t->finalvol=checkvol(t->finalvol-(4<<((t->retrig>>4)-1)));
1086 break;
1087 case 6:
1088 t->vol=t->finalvol=checkvol(t->finalvol*5/8); /* s3m only? */
1089 break;
1090 case 7:
1091 t->vol=t->finalvol=checkvol(t->finalvol/2);
1092 break;
1093 case 9: case 10: case 11: case 12: case 13:
1094 t->vol=t->finalvol=checkvol(t->finalvol+(4<<((t->retrig>>4)-9)));
1095 break;
1096 case 14:
1097 t->vol=t->finalvol=checkvol(t->finalvol*3/2);
1098 break;
1099 case 15:
1100 t->vol=t->finalvol=checkvol(t->finalvol*2);
1101 break;
1102 }
1103 }
1104 t->retrigpos++;
1105 break;
1106 }
1107 }
1108
putque(int time,int type,int val1,int val2)1109 static void putque(int time, int type, int val1, int val2)
1110 {
1111 if (((quewpos+1)%quelen)==querpos)
1112 return;
1113 que[quewpos][0]=time;
1114 que[quewpos][1]=type;
1115 que[quewpos][2]=val1;
1116 que[quewpos][3]=val2;
1117 quewpos=(quewpos+1)%quelen;
1118 }
1119
PlayTick(void)1120 static void PlayTick(void)
1121 {
1122 struct trackdata *td;
1123 int i;
1124
1125 int cmdtime;
1126
1127 if (!physchan)
1128 return;
1129
1130 for (i=0; i<physchan; i++)
1131 if (!mcpGet(i, mcpCStatus))
1132 if (pchan[i]!=-1)
1133 {
1134 mcpSet(i, mcpCReset, 0);
1135 tdata[pchan[i]].phys=-1;
1136 pchan[i]=-1;
1137 }
1138
1139 for (td=tdata; td<tdataend; td++)
1140 {
1141 td->finalvol=td->vol;
1142 td->finalpan=td->pan;
1143 td->finalpitch=td->pitch;
1144 td->newpos=(uint_fast32_t)-1;
1145 td->newposend=0;
1146 td->newdir=-1;
1147 td->newloop=-1;
1148 td->stopchan=0;
1149 td->newinst=-1;
1150 }
1151
1152 currenttick++;
1153 if (currenttick>=tempo)
1154 currenttick=0;
1155
1156 if (!currenttick&&patdelay)
1157 {
1158 brkpat=currentpattern;
1159 brkrow=currentrow;
1160 /* patdelay--; */
1161 }
1162
1163 processtick=newtickmode||currenttick||patdelay;
1164
1165 if (!currenttick/*&&!patdelay*/)
1166 {
1167 currenttick=0;
1168
1169 currentrow++;
1170
1171 if ((currentrow>=patternlen)&&(brkpat==-1))
1172 {
1173 brkpat=currentpattern+1;
1174 donotshutup=0;
1175 if (brkpat==endpat)
1176 {
1177 looped=1;
1178 brkpat=looppat;
1179 }
1180 brkrow=0;
1181 }
1182 if (brkpat!=-1)
1183 {
1184 if (currentpattern!=brkpat)
1185 {
1186 if (lockpattern!=-1)
1187 {
1188 if (brkpat!=lockpattern)
1189 brkrow=0;
1190 brkpat=lockpattern;
1191 donotshutup=1;
1192 }
1193 memset(patloopcount, 0, sizeof(patloopcount));
1194 memset(patlooprow, 0, sizeof(patlooprow));
1195 }
1196 currentpattern=brkpat;
1197 currentrow=brkrow;
1198 brkpat=-1;
1199 brkrow=0;
1200 while ((currentpattern<patternnum)&&(orders[currentpattern]==0xFFFF))
1201 currentpattern++;
1202 if ((currentpattern>=patternnum)||(currentpattern==endpat))
1203 {
1204 currentpattern=looppat;
1205 looped=1;
1206 }
1207 if (!currentpattern&&!currentrow&&!patdelay&&!donotshutup)
1208 {
1209 currentpattern=0;
1210 currentrow=0;
1211 for (i=0; i<channels; i++)
1212 {
1213 int mute=tdata[i].mute;
1214 memset(&tdata[i], 0, sizeof(*tdata));
1215 tdata[i].mute=mute;
1216 tdata[i].num=i;
1217 tdata[i].chanvol=0xFF;
1218 tdata[i].finalpan=tdata[i].pan=(i&1)?255:0;
1219 tdata[i].newpos=(uint_fast32_t)-1;
1220 tdata[i].newloop=-1;
1221 tdata[i].newdir=-1;
1222 tdata[i].newinst=-1;
1223 tdata[i].phys=-1;
1224 }
1225 for (i=0; i<physchan; i++)
1226 {
1227 mcpSet(i, mcpCReset, 0);
1228 pchan[i]=-1;
1229 }
1230 tempo=6;
1231 speed=125;
1232 globalvol=0xFF;
1233 mcpSet(-1, mcpGSpeed, 12800);
1234 }
1235 LoadPattern(currentpattern, currentrow);
1236 }
1237
1238 memset(globalvolslide, 0, sizeof(globalvolslide));
1239
1240 for (td=tdata; td<tdataend; td++)
1241 {
1242 struct gmdtrack *t;
1243 td->notehit=0;
1244 td->volslide=0;
1245 td->pitchslide=0;
1246 td->panslide=0;
1247 td->pitchfx=0;
1248 td->volfx=0;
1249 td->panfx=0;
1250 td->notefx=0;
1251 td->delay=-1;
1252 td->fx=0;
1253
1254 t=&td->trk;
1255 while (1)
1256 {
1257 if (t->ptr>=t->end)
1258 break;
1259 if (t->ptr[0]!=currentrow)
1260 break;
1261 PlayCommand(td, t->ptr+2, t->ptr[1]);
1262 t->ptr+=t->ptr[1]+2;
1263 }
1264 }
1265
1266 while (1)
1267 {
1268 if (gtrack.ptr>=gtrack.end)
1269 break;
1270 if (gtrack.ptr[0]!=currentrow)
1271 break;
1272 PlayGCommand(gtrack.ptr+2, gtrack.ptr[1]);
1273 gtrack.ptr+=gtrack.ptr[1]+2;
1274 }
1275
1276 if (patdelay)
1277 patdelay--;
1278 }
1279
1280 DoGCommand();
1281 for (td=tdata; td<tdataend; td++)
1282 DoCommand(td);
1283
1284 for (td=tdata; td<tdataend; td++)
1285 {
1286 int16_t vol, pan;
1287 /* const struct gmdinstrument *f; */
1288 const struct gmdsample *fs;
1289 if (!td->instr)
1290 continue;
1291 if (!td->samp)
1292 continue;
1293 vol=(td->finalvol*globalvol)>>8;
1294 pan=td->finalpan-0x80;
1295 /* f=&*td->instr; */
1296 fs=&*td->samp;
1297
1298 if (!td->sustain&&fs->volfade)
1299 {
1300 vol=(vol*td->fadevol)>>15;
1301 if (td->fadevol>=fs->volfade)
1302 td->fadevol-=fs->volfade;
1303 else
1304 td->fadevol=0;
1305 }
1306
1307 if (fs->volenv<envnum)
1308 {
1309 const struct gmdenvelope *env=&envelopes[fs->volenv];
1310 vol=(env->env[td->venvpos]*vol)>>8;
1311
1312 if (!env->speed||(env->speed==speed))
1313 td->venvfrac+=65536;
1314 else
1315 td->venvfrac+=env->speed*65536/speed;
1316
1317 while (td->venvfrac>=65536)
1318 {
1319 if (td->venvpos<env->len)
1320 td->venvpos++;
1321 if (td->sustain&&(env->type&mpEnvSLoop))
1322 {
1323 if (td->venvpos==env->sloope)
1324 td->venvpos=env->sloops;
1325 } else if (env->type&mpEnvLoop)
1326 {
1327 if (td->venvpos==env->loope)
1328 td->venvpos=env->loops;
1329 }
1330 td->venvfrac-=65536;
1331 }
1332 }
1333 if (fs->panenv<envnum)
1334 {
1335 const struct gmdenvelope *env=&envelopes[fs->panenv];
1336 pan+=((env->env[td->penvpos]-128)*(128-abs(pan)))>>7;
1337
1338 if (!env->speed||(env->speed==speed))
1339 td->penvfrac+=65536;
1340 else
1341 td->penvfrac+=env->speed*65536/speed;
1342
1343 while (td->penvfrac>=65536)
1344 {
1345 if (td->penvpos<env->len)
1346 td->penvpos++;
1347 if (td->sustain&&(env->type&mpEnvSLoop))
1348 {
1349 if (td->penvpos==env->sloope)
1350 td->penvpos=env->sloops;
1351 } else if (env->type&mpEnvLoop)
1352 {
1353 if (td->penvpos==env->loope)
1354 td->penvpos=env->loops;
1355 }
1356 td->penvfrac-=65536;
1357 }
1358 }
1359
1360 if (fs->pchenv<envnum)
1361 {
1362 const struct gmdenvelope *env=&envelopes[fs->pchenv];
1363 int16_t dep=((env->env[td->pchenvpos]-128)<<fs->pchint)>>1;
1364
1365 if (expopitchenv&&!exponential)
1366 td->finalpitch=checkpitch(umuldiv(td->finalpitch, mcpGetFreq8363(dep), 8363));
1367 else
1368 td->finalpitch=checkpitch(td->finalpitch-dep);
1369
1370 if (!env->speed||(env->speed==speed))
1371 td->pchenvfrac+=65536;
1372 else
1373 td->pchenvfrac+=env->speed*65536/speed;
1374
1375 while (td->pchenvfrac>=65536)
1376 {
1377 if (td->pchenvpos<env->len)
1378 td->pchenvpos++;
1379 if (td->sustain&&(env->type&mpEnvSLoop))
1380 {
1381 if (td->pchenvpos==env->sloope)
1382 td->pchenvpos=env->sloops;
1383 } else if (env->type&mpEnvLoop)
1384 {
1385 if (td->pchenvpos==env->loope)
1386 td->pchenvpos=env->loops;
1387 }
1388 td->pchenvfrac-=65536;
1389 }
1390 }
1391 if (fs->vibrate&&fs->vibdepth)
1392 {
1393 int dep=0;
1394 switch (fs->vibtype)
1395 {
1396 case 0:
1397 dep=(sintab[(td->vibenvpos>>8)&0xFF]*fs->vibdepth)>>11;
1398 break;
1399 case 1:
1400 dep=(td->vibenvpos&0x8000)?-fs->vibdepth:fs->vibdepth;
1401 break;
1402 case 2:
1403 dep=(fs->vibdepth*(32768-td->vibenvpos))>>14;
1404 break;
1405 case 3:
1406 dep=(fs->vibdepth*(td->vibenvpos-32768))>>14;
1407 break;
1408 }
1409
1410 td->vibsweeppos+=fs->vibsweep;
1411 if (td->vibsweeppos<0) /* currently not needed, check is compiled out anyways */
1412 td->vibsweeppos=0;
1413 if (td->vibsweeppos>0x10000)
1414 td->vibsweeppos=0x10000;
1415 dep=(dep*td->vibsweeppos)>>16;
1416
1417 if (expopitchenv&&!exponential)
1418 td->finalpitch=checkpitch(umuldiv(td->finalpitch, mcpGetFreq8363(dep), 8363));
1419 else
1420 td->finalpitch=checkpitch(td->finalpitch-dep);
1421
1422 if (!fs->vibspeed||(fs->vibspeed==speed))
1423 td->vibenvpos+=fs->vibrate;
1424 else
1425 td->vibenvpos+=fs->vibspeed*fs->vibrate/speed;
1426 }
1427 /*
1428 if (fs.vibenv!=0xFFFF)
1429 {
1430 const envelope &env=envelopes[fs.vibenv];
1431 signed short dep=((env.env[td->vibenvpos]-128)<<fs.vibint)>>1;
1432 if (td->vibsweeppos!=fs.vibswp)
1433 dep=dep*td->vibsweeppos/fs.vibswp;
1434
1435 if (expopitchenv&&!exponential)
1436 td->finalpitch=checkpitch(umuldiv(td->finalpitch, mcpGetFreq8363(dep), 8363));
1437 else
1438 td->finalpitch=checkpitch(td->finalpitch-dep);
1439
1440 if (!env.speed||(env.speed==speed))
1441 td->vibenvfrac+=65536;
1442 else
1443 td->vibenvfrac+=env.speed*65536/speed;
1444
1445 while (td->vibenvfrac>=65536)
1446 {
1447 if (td->vibsweeppos!=fs.vibswp)
1448 td->vibsweeppos++;
1449 if ((td->vibenvpos<env.len)&&((td->vibenvpos!=env.sustain)||!td->sustain))
1450 td->vibenvpos++;
1451 if ((td->vibenvpos==env.loope)&&(td->sustain||!(env.opt&1)))
1452 td->vibenvpos=env.loops;
1453 td->vibenvfrac-=65536;
1454 }
1455 }
1456 */
1457
1458 if (gusvol)
1459 {
1460 if (vol>0xEF)
1461 vol=0xFF;
1462 else
1463 if (vol<0)
1464 vol=0;
1465 else
1466 if (vol>=0xB0)
1467 vol=((vol&0xF)|0x10)<<((vol>>4)-0xB);
1468 else
1469 vol=((vol&0xF)|0x10)>>(0xB-(vol>>4));
1470 }
1471 vol=(vol*td->chanvol)>>8;
1472
1473 if (td->newinst!=-1)
1474 if (td->phys!=-1)
1475 mcpSet(td->phys, mcpCInstrument, td->newinst);
1476 if (td->newpos!=(uint_fast32_t)-1)
1477 {
1478 uint_fast32_t l;
1479 const struct sampleinfo *sm;
1480 if (td->phys==-1)
1481 {
1482 for (i=0; i<physchan; i++)
1483 if (pchan[i]==-1)
1484 break;
1485 if (i==physchan)
1486 i=rand()%physchan;
1487 if (pchan[i]!=-1)
1488 tdata[pchan[i]].phys=-1;
1489 pchan[i]=td->num;
1490 td->phys=i;
1491 mcpSet(td->phys, mcpCReset, 0);
1492 mcpSet(td->phys, mcpCInstrument, td->samp->handle);
1493 }
1494 sm=&sampleinfos[td->samp->handle];
1495 l=sm->length;
1496 if (sm->type&mcpSampRedRate4)
1497 l>>=2;
1498 else if (sm->type&mcpSampRedRate2)
1499 l>>=1;
1500 if (td->newposend)
1501 td->newpos=l-td->newpos;
1502 if (td->newpos>=l)
1503 td->newpos=l-16;
1504
1505 mcpSet(td->phys, mcpCPosition, td->newpos);
1506 mcpSet(td->phys, mcpCLoop, 1);
1507 mcpSet(td->phys, mcpCDirect, 0);
1508 mcpSet(td->phys, mcpCStatus, 1);
1509 }
1510 if (td->newdir!=-1)
1511 mcpSet(td->phys, mcpCDirect, td->newdir);
1512 if (td->newloop!=-1)
1513 mcpSet(td->phys, mcpCLoop, td->newloop);
1514 if (td->phys!=-1)
1515 {
1516 if (td->stopchan)
1517 mcpSet(td->phys, mcpCStatus, 0);
1518 mcpSet(td->phys, mcpCVolume, (donotloopmodule&&looped)?0:vol);
1519 mcpSet(td->phys, mcpCPanning, pan);
1520 mcpSet(td->phys, mcpCPanY, td->pany);
1521 mcpSet(td->phys, mcpCPanZ, td->panz);
1522 mcpSet(td->phys, mcpCSurround, td->pansrnd);
1523 if (exponential)
1524 mcpSet(td->phys, mcpCPitch, -checkpitche(td->finalpitch));
1525 else
1526 mcpSet(td->phys, mcpCPitch6848, checkpitchh(td->finalpitch));
1527 mcpSet(td->phys, mcpCMute, td->mute);
1528 }
1529 }
1530 readque();
1531 cmdtime=mcpGet(-1, mcpGCmdTimer);
1532 putque(cmdtime, -1, (currentrow<<8)|(currentpattern<<16), 0);
1533 }
1534
mpPlayModule(const struct gmdmodule * m,struct ocpfilehandle_t * file)1535 char __attribute__ ((visibility ("internal"))) mpPlayModule(const struct gmdmodule *m, struct ocpfilehandle_t *file)
1536 {
1537 int i;
1538 for (i=65; i<=128; i++)
1539 sintab[i]=sintab[128-i];
1540 for (i=129; i<256; i++)
1541 sintab[i]=-sintab[256-i];
1542
1543 if (m->orders[0]==0xFFFF)
1544 return 0;
1545
1546 sampleinfos=m->samples;
1547 modsampnum=m->modsampnum;
1548 sampnum=m->sampnum;
1549 lockpattern=-1;
1550 patterns=m->patterns;
1551 orders=m->orders;
1552 envelopes=m->envelopes;
1553 instruments=m->instruments;
1554 instnum=m->instnum;
1555 modsamples=m->modsamples;
1556 patternnum=m->ordnum;
1557 channels=m->channum;
1558 envnum=m->envnum;
1559 tdataend=tdata+channels;
1560 tracks=m->tracks;
1561 looppat=(m->loopord<m->ordnum)?m->loopord:0;
1562 while (m->orders[looppat]==0xFFFF)
1563 looppat--;
1564
1565 endpat=m->endord;
1566 samiextrawurscht=!!(m->options&MOD_S3M);
1567 samisami=!!(m->options&MOD_S3M30);
1568 newtickmode=!!(m->options&MOD_TICK0);
1569 exponential=!!(m->options&MOD_EXPOFREQ);
1570 gusvol=!!(m->options&MOD_GUSVOL);
1571 expopitchenv=!!(m->options&MOD_EXPOPITCHENV);
1572 donotshutup=0;
1573
1574 tempo=6;
1575 patdelay=0;
1576 patternlen=0;
1577 currenttick=tempo;
1578 currentrow=0;
1579 currentpattern=0;
1580 looped=0;
1581 brkpat=0;
1582 brkrow=0;
1583 speed=125;
1584 globalvol=0xFF;
1585 realpos=0;
1586
1587 for (i=0; i<channels; i++)
1588 {
1589 tdata[i].phys=-1;
1590 tdata[i].mute=0;
1591 }
1592 memset(pchan, -1, sizeof(pchan));
1593
1594 quelen=100;
1595 que=malloc(sizeof(int)*quelen*4);
1596 if (!que)
1597 return 0;
1598 querpos=0;
1599 quewpos=0;
1600
1601 if (!mcpOpenPlayer(channels, PlayTick, file))
1602 return 0;
1603
1604 physchan=mcpNChan;
1605
1606 return 1;
1607 }
1608
mpStopModule(void)1609 void __attribute__ ((visibility ("internal"))) mpStopModule(void)
1610 {
1611 int i;
1612 for (i=0; i<physchan; i++)
1613 mcpSet(i, mcpCReset, 0);
1614 mcpClosePlayer();
1615 free(que);
1616 }
1617
mpGetChanInfo(uint8_t ch,struct chaninfo * ci)1618 void __attribute__ ((visibility ("internal"))) mpGetChanInfo(uint8_t ch, struct chaninfo *ci)
1619 {
1620 const struct trackdata *t=&tdata[ch];
1621 ci->ins=0xFF;
1622 ci->smp=0xFFFF;
1623 if (t->instr)
1624 {
1625 if (t->samp)
1626 ci->smp=t->samp-modsamples;
1627 ci->ins=t->instr-instruments;
1628 }
1629 ci->note=t->nteval;
1630 ci->vol=t->vol;
1631 if (!t->fadevol)
1632 ci->vol=0;
1633 ci->pan=t->pan;
1634 ci->notehit=t->notehit;
1635 ci->volslide=t->volslide;
1636 ci->pitchslide=t->pitchslide;
1637 ci->panslide=t->panslide;
1638 ci->volfx=t->volfx;
1639 ci->pitchfx=t->pitchfx;
1640 ci->notefx=t->notefx;
1641 ci->fx=t->fx;
1642 }
1643
1644
1645
mpGetRealNote(uint8_t ch)1646 uint16_t __attribute__ ((visibility ("internal"))) mpGetRealNote(uint8_t ch)
1647 {
1648 struct trackdata *td=&tdata[ch];
1649 if (exponential)
1650 return 60*256+td->samp->normnote-checkpitche(td->finalpitch);
1651 else
1652 return 60*256+td->samp->normnote+mcpGetNote8363(6848*8363/checkpitchh(td->finalpitch));
1653 /* return td.nteval<<8; */
1654 }
1655
mpGetGlobInfo(struct globinfo * gi)1656 void __attribute__ ((visibility ("internal"))) mpGetGlobInfo(struct globinfo *gi)
1657 {
1658 int i;
1659
1660 gi->speed=speed;
1661 gi->curtick=currenttick;
1662 gi->tempo=tempo;
1663 gi->currow=currentrow;
1664 gi->patlen=patternlen;
1665 gi->curpat=currentpattern;
1666 gi->patnum=patternnum;
1667 gi->globvol=globalvol;
1668 gi->globvolslide=0;
1669 for (i=0; i<MAXLCHAN; i++)
1670 if (globalvolslide[i])
1671 gi->globvolslide=globalvolslide[i];
1672 }
1673
mpGetPosition(uint16_t * pat,uint8_t * row)1674 void __attribute__ ((visibility ("internal"))) mpGetPosition(uint16_t *pat, uint8_t *row)
1675 {
1676 *pat=currentpattern;
1677 *row=currentrow;
1678 }
1679
mpGetRealPos(void)1680 int __attribute__ ((visibility ("internal"))) mpGetRealPos(void)
1681 {
1682 readque();
1683 return realpos;
1684 }
1685
mpSetPosition(int16_t pat,int16_t row)1686 void __attribute__ ((visibility ("internal"))) mpSetPosition(int16_t pat, int16_t row)
1687 {
1688 unsigned int i;
1689 if (row<0)
1690 pat--;
1691 if (pat<0)
1692 {
1693 pat=0;
1694 row=0;
1695 }
1696 if (pat>=patternnum)
1697 {
1698 pat=looppat;
1699 row=0;
1700 }
1701 if (row<0)
1702 {
1703 while (orders[pat]==0xFFFF)
1704 pat--;
1705 row+=patterns[orders[pat]].patlen;
1706 if (row<0)
1707 row=0;
1708 }
1709 while ((pat<patternnum)&&(orders[pat]==0xFFFF))
1710 pat++;
1711 if (pat>=patternnum)
1712 {
1713 pat=looppat;
1714 row=0;
1715 }
1716 if (row>patterns[orders[pat]].patlen)
1717 {
1718 pat++;
1719 row=0;
1720 if (pat>=patternnum)
1721 pat=looppat;
1722 }
1723 if (pat!=currentpattern)
1724 {
1725 if (lockpattern!=-1)
1726 lockpattern=pat;
1727 for (i=0; i<physchan; i++)
1728 {
1729 mcpSet(i, mcpCReset, 0);
1730 pchan[i]=-1;
1731 }
1732 for (i=0; i<channels; i++)
1733 tdata[i].phys=-1;
1734 }
1735 donotshutup=0;
1736 patdelay=0;
1737 brkpat=pat;
1738 brkrow=row;
1739 currentpattern=pat;
1740 currentrow=row;
1741 currenttick=tempo;
1742 }
1743
mpLooped(void)1744 char __attribute__ ((visibility ("internal"))) mpLooped(void)
1745 {
1746 return looped;
1747 }
1748
mpSetLoop(uint8_t s)1749 void __attribute__ ((visibility ("internal"))) mpSetLoop(uint8_t s)
1750 {
1751 donotloopmodule=!s;
1752 }
1753
mpLockPat(int st)1754 void __attribute__ ((visibility ("internal"))) mpLockPat(int st)
1755 {
1756 if (st)
1757 lockpattern=currentpattern;
1758 else
1759 lockpattern=-1;
1760 }
1761
mpGetChanSample(unsigned int ch,int16_t * buf,unsigned int len,uint32_t rate,int opt)1762 int __attribute__ ((visibility ("internal"))) mpGetChanSample(unsigned int ch, int16_t *buf, unsigned int len, uint32_t rate, int opt)
1763 {
1764 if (tdata[ch].phys==-1)
1765 {
1766 memset(buf, 0, len*2);
1767 return 1;
1768 }
1769 return mcpGetChanSample(tdata[ch].phys, buf, len, rate, opt);
1770 }
1771
mpMute(int ch,int mute)1772 void __attribute__ ((visibility ("internal"))) mpMute(int ch, int mute)
1773 {
1774 tdata[ch].mute=mute;
1775 if (tdata[ch].phys!=-1)
1776 mcpSet(tdata[ch].phys, mcpCMute, mute);
1777 }
1778
mpGetMute(int ch)1779 int __attribute__ ((visibility ("internal"))) mpGetMute(int ch)
1780 {
1781 return tdata[ch].mute;
1782 }
1783
mpGetChanStatus(int ch)1784 int __attribute__ ((visibility ("internal"))) mpGetChanStatus(int ch)
1785 {
1786 if (tdata[ch].phys==-1)
1787 return 0;
1788 return mcpGet(tdata[ch].phys, mcpCStatus);
1789 }
1790
mpGetRealVolume(int ch,int * l,int * r)1791 void __attribute__ ((visibility ("internal"))) mpGetRealVolume(int ch, int *l, int *r)
1792 {
1793 if (tdata[ch].phys==-1)
1794 {
1795 *l=*r=0;
1796 return;
1797 }
1798 mcpGetRealVolume(tdata[ch].phys, l, r);
1799 }
1800
mpLoadSamples(struct gmdmodule * m)1801 int __attribute__ ((visibility ("internal"))) mpLoadSamples(struct gmdmodule *m)
1802 {
1803 return mcpLoadSamples(m->samples, m->sampnum);
1804 }
1805