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(&gtrack, 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