1 /* Copyright (c) 2003-2021 James Daniels */
2 /* Distributed under the MIT License */
3 /* license terms: see LICENSE file in root or http://opensource.org/licenses/MIT */
5 #include "AAS_Shared.h"
7 AAS_s16 AAS_mod_num AAS_IN_EWRAM = -1;
8 AAS_u8 AAS_mod_num_chans AAS_IN_EWRAM = 0;
10 static AAS_s16 AAS_mod_num_store AAS_IN_EWRAM = -2;
11 static AAS_u16 AAS_mod_song_pos AAS_IN_EWRAM;
12 static AAS_u16 AAS_mod_line_num AAS_IN_EWRAM;
14 struct AAS_MOD_Channel {
16 const AAS_u8 *samp_start;
19 AAS_u16 slide_target_period;
34 static struct AAS_MOD_Channel AAS_mod_chan[AAS_MAX_CHANNELS] AAS_IN_EWRAM;
36 static AAS_s32 AAS_mod_timer AAS_IN_EWRAM;
37 static AAS_u32 AAS_mod_tempo AAS_IN_EWRAM;
38 static AAS_u8 AAS_mod_bpm AAS_IN_EWRAM;
39 static AAS_u8 AAS_mod_speed AAS_IN_EWRAM;
40 static AAS_BOOL AAS_mod_looped AAS_IN_EWRAM = AAS_FALSE;
41 static AAS_s16 AAS_mod_overall_volume AAS_IN_EWRAM = 256;
42 static AAS_u8 AAS_mod_loop_start AAS_IN_EWRAM = 0;
43 static AAS_s8 AAS_mod_loop_counter AAS_IN_EWRAM = 0;
44 static AAS_BOOL AAS_mod_loop AAS_IN_EWRAM = AAS_TRUE;
45 static AAS_u8 AAS_mod_last_filter_value AAS_IN_EWRAM = 0;
46 static AAS_BOOL AAS_mod_active_effects AAS_IN_EWRAM = AAS_FALSE;
47 static AAS_s8 AAS_mod_next_song_pos AAS_IN_EWRAM = -1;
49 int AAS_MOD_GetNumChannels()
51 return AAS_mod_num_chans;
54 int AAS_MOD_GetLastFilterValue()
56 return AAS_mod_last_filter_value;
59 int AAS_MOD_QueueSongPos(int song_pos)
61 if(AAS_mod_num >= 0) {
62 if((song_pos >= 0) && (song_pos < 128)) {
63 if(AAS_Sequence[AAS_mod_num][song_pos][0] == -1) {
64 return AAS_ERROR_INVALID_SONG_POS;
66 AAS_mod_next_song_pos = song_pos;
71 return AAS_ERROR_INVALID_SONG_POS;
74 return AAS_ERROR_NO_MOD_PLAYING;
78 int AAS_MOD_SetSongPos(int song_pos)
80 if(AAS_mod_num >= 0) {
81 if((song_pos >= 0) && (song_pos < 128)) {
82 if(AAS_Sequence[AAS_mod_num][song_pos][0] == -1) {
83 return AAS_ERROR_INVALID_SONG_POS;
85 struct AAS_MOD_Channel *mod_chan = AAS_mod_chan;
88 for(chan = 0; chan < AAS_mod_num_chans; ++chan) {
90 (AAS_u32 *) (AAS_PatternData +
92 AAS_Sequence[AAS_mod_num][song_pos]
97 AAS_mod_song_pos = song_pos;
102 return AAS_ERROR_INVALID_SONG_POS;
105 return AAS_ERROR_NO_MOD_PLAYING;
109 int AAS_MOD_GetSongPos()
112 return AAS_mod_song_pos;
114 return AAS_ERROR_NO_MOD_PLAYING;
117 int AAS_MOD_GetLineNum()
120 return AAS_mod_line_num;
122 return AAS_ERROR_NO_MOD_PLAYING;
125 int AAS_MOD_GetVolume()
127 return AAS_mod_overall_volume;
130 int AAS_MOD_SetVolume(int vol)
132 if((vol >= 0) && (vol <= 256)) {
135 for(i = AAS_mod_num_chans - 1; i >= 0; --i)
136 AAS_channels[AAS_chan_rearrange[i]].volume = (AAS_mod_chan[i].volume * vol) >> AAS_volscale;
138 AAS_mod_overall_volume = vol;
142 return AAS_ERROR_VOLUME_OUT_OF_RANGE;
150 AAS_mod_num_store = AAS_mod_num;
153 for(i = 0; i < AAS_mod_num_chans; ++i) {
154 AAS_channels[AAS_chan_rearrange[i]].active = AAS_FALSE;
158 void AAS_MOD_Resume()
160 if(AAS_mod_num_store != -2) {
161 struct AAS_Channel *ch;
164 for(i = 0; i < AAS_mod_num_chans; ++i) {
165 ch = &AAS_channels[AAS_chan_rearrange[i]];
168 if(ch->loop_length) {
169 ch->active = AAS_TRUE;
171 if(ch->pos < ((ch->end - (ch->delta >> 6)) - 1)) {
172 ch->active = AAS_TRUE;
178 AAS_mod_num = AAS_mod_num_store;
185 struct AAS_Channel *ch;
187 AAS_mod_num_store = -2;
189 AAS_mod_next_song_pos = -1;
191 for(i = 0; i < AAS_mod_num_chans; ++i) {
192 ch = &AAS_channels[AAS_chan_rearrange[i]];
193 ch->active = AAS_FALSE;
198 AAS_mod_chan[i].tremolo_pos = 0;
199 AAS_mod_chan[i].vibrato_pos = 0;
200 AAS_mod_chan[i].effect = 0;
201 AAS_mod_chan[i].volume = 0;
202 AAS_mod_chan[i].trigger = -1;
203 AAS_mod_chan[i].note = 0;
204 AAS_mod_chan[i].slide_target_period = 0;
206 AAS_mod_active_effects = AAS_FALSE;
207 AAS_mod_looped = AAS_FALSE;
208 AAS_mod_loop_counter = 0;
209 AAS_mod_loop_start = 0;
210 AAS_mod_last_filter_value = 0;
211 AAS_mod_num_chans = 0;
214 AAS_BOOL AAS_MOD_HasLooped()
216 return AAS_mod_looped;
219 AAS_BOOL AAS_MOD_IsPlaying()
221 return (AAS_mod_num >= 0);
224 int AAS_MOD_Play(int song_num)
228 if(AAS_initialised) {
229 if((song_num >= 0) && (song_num < AAS_DATA_NUM_MODS) && AAS_NumChans[song_num]) {
232 if(AAS_volscale == 9)
234 else if(AAS_volscale == 8)
239 if(AAS_NumChans[song_num] > i) {
240 return AAS_ERROR_NOT_ENOUGH_CHANNELS;
242 /*AAS_mod_num = 0; */
243 AAS_mod_loop = AAS_TRUE;
244 AAS_mod_num_store = -2;
245 AAS_mod_song_pos = 0;
246 AAS_mod_num_chans = AAS_NumChans[song_num];
248 for(i = 0; i < AAS_mod_num_chans; ++i)
249 AAS_mod_chan[i].pattern = (AAS_u32 *) (AAS_PatternData + (((int)AAS_Sequence[song_num][0][i]) << 8));
251 AAS_mod_line_num = 0;
254 AAS_mod_tempo = AAS_DivTable[AAS_mod_speed] * AAS_mod_bpm;
255 AAS_mod_timer = 0x7d0000 - AAS_mod_tempo;
256 AAS_mod_num = song_num;
260 return AAS_ERROR_MOD_DOES_NOT_EXIST;
263 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
267 int AAS_MOD_SetLoop(AAS_BOOL loop)
269 if(AAS_initialised) {
270 if(AAS_mod_num >= 0) {
274 return AAS_ERROR_NO_MOD_PLAYING;
277 return AAS_ERROR_CALL_SET_CONFIG_FIRST;
281 void AAS_MOD_Interrupt()
283 if(AAS_mod_num >= 0) {
284 AAS_mod_timer += AAS_mod_tempo;
286 if(AAS_mod_timer < 0x7d0000) {
287 if(AAS_mod_active_effects) {
288 const AAS_u8 *chan_rearrange = AAS_chan_rearrange;
289 struct AAS_MOD_Channel *mod_chan = AAS_mod_chan;
292 num_chans = AAS_mod_num_chans;
294 for(chan = 0; chan < num_chans; ++chan) {
297 effect = mod_chan->effect;
300 int val, tmp, output;
301 struct AAS_Channel *out_chan;
303 tmp = chan_rearrange[chan];
304 out_chan = &AAS_channels[tmp];
307 switch (effect >> 8) {
308 case 0xe: /* extended effects */
309 switch (effect & 0xf0) {
310 case 0xc0: /* note cut */
314 mod_chan->effect = 0;
315 out_chan->active = AAS_FALSE;
317 AAS_changed[output] = AAS_TRUE;
319 mod_chan->effect = (effect & 0xff0) + val;
323 case 0x90: /* retrigger sample */
324 case 0xd0: /* delay sample */
325 if(mod_chan->trigger >= 0) {
327 if(mod_chan->trigger < 0) {
328 const struct AAS_ModSample *samp = &AAS_ModSamples[AAS_mod_num][mod_chan->samp_num];
329 int repeat = samp->repeat;
330 int length = samp->length;
331 const AAS_s8 *data = AAS_SampleData + samp->data;
333 mod_chan->samp_start = data;
334 out_chan->pos = data;
335 out_chan-> pos_fraction = 0;
337 out_chan->loop_length = 0;
339 out_chan->loop_length = ((AAS_u32) (length - repeat)) << 1;
340 out_chan->end = data + (length << 1);
341 out_chan->frequency = AAS_MOD_period_conv_table[mod_chan->period];
342 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
343 out_chan->active = AAS_TRUE;
345 AAS_changed[output] = AAS_TRUE;
355 case 0x6: /* vibrato + volume slide */
356 val = mod_chan->vibrato_pos;
357 val += mod_chan->vibrato_rate;
360 mod_chan->vibrato_pos = val;
361 tmp = mod_chan->period + (((AAS_sin[val] * mod_chan->vibrato_depth) + 32) >> 6);
366 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
367 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
368 /* Intentionally no "break;" */
370 case 0xa: /* volume slide */
375 val = -(effect & 0xf);
376 tmp = mod_chan->volume;
382 mod_chan->volume = tmp;
383 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
385 AAS_changed[output] = AAS_TRUE;
388 case 0x1: /* slide up */
390 tmp = mod_chan->period - val;
393 mod_chan->period = tmp;
394 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
395 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
397 AAS_changed[output] = AAS_TRUE;
400 case 0x2: /* slide down */
402 tmp = mod_chan->period + val;
405 mod_chan->period = tmp;
406 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
407 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
409 AAS_changed[output] = AAS_TRUE;
412 case 0x3: /* tone portamento */
413 val = mod_chan->period;
414 tmp = mod_chan->slide_target_period;
416 val += mod_chan->slide_rate;
418 mod_chan->effect = 0;
421 } else if(val > tmp) {
422 val -= mod_chan->slide_rate;
424 mod_chan->effect = 0;
427 } else if(val == tmp) {
428 mod_chan->effect = 0;
430 mod_chan->period = val;
431 out_chan->frequency = AAS_MOD_period_conv_table[val];
432 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
434 AAS_changed[output] = AAS_TRUE;
437 case 0x5: /* tone portamento + volume slide */
438 val = mod_chan->period;
439 tmp = mod_chan->slide_target_period;
441 val += mod_chan->slide_rate;
444 } else if(val > tmp) {
445 val -= mod_chan->slide_rate;
449 mod_chan->period = val;
450 out_chan->frequency = AAS_MOD_period_conv_table[val];
451 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
457 val = -(effect & 0xf);
458 tmp = mod_chan->volume;
464 mod_chan->volume = tmp;
465 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
467 AAS_changed[output] = AAS_TRUE;
470 case 0x4: /* vibrato */
471 val = mod_chan->vibrato_pos;
472 val += mod_chan->vibrato_rate;
475 mod_chan->vibrato_pos = val;
476 tmp = mod_chan->period + (((AAS_sin[val] * mod_chan->vibrato_depth) + 32) >> 6);
481 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
482 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
484 AAS_changed[output] = AAS_TRUE;
487 case 0x7: /* tremolo */
488 val = mod_chan->tremolo_pos;
489 val += mod_chan->tremolo_rate;
492 mod_chan->tremolo_pos = val;
493 tmp = mod_chan->volume + (((AAS_sin[val] * mod_chan->tremolo_depth) + 32) >> 6);
498 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
500 AAS_changed[output] = AAS_TRUE;
503 case 0x0: /* possible arpeggio */
505 if(tmp) /* definite arpeggio */
507 ++mod_chan->arpeggio_pos;
508 val = mod_chan->note;
509 switch (mod_chan->arpeggio_pos) {
519 /* Intentionally no "break;" to allow AAS_mod_arpeggio_pos[chan] to be restarted */
522 mod_chan->arpeggio_pos = 0;
527 out_chan->frequency = AAS_MOD_period_conv_table[AAS_period_table[AAS_ModSamples[AAS_mod_num][mod_chan->samp_num].finetune][val - 1]];
528 out_chan->delta = AAS_Min(4095, ((out_chan-> frequency * AAS_mix_scale) + 32768) >> 16);
530 AAS_changed[output] = AAS_TRUE;
544 const AAS_u8 *chan_rearrange = AAS_chan_rearrange;
545 struct AAS_MOD_Channel *mod_chan = AAS_mod_chan;
547 int samp_num, effect, period, speed, tmp;
549 int jump_song_pos = -1;
550 AAS_BOOL active_effects = AAS_FALSE;
551 const struct AAS_ModSample *mod_samp = AAS_ModSamples[AAS_mod_num];
553 num_chans = AAS_mod_num_chans;
555 AAS_mod_timer -= 0x7d0000;
557 for(chan = 0; chan < num_chans; ++chan) {
559 struct AAS_Channel *out_chan;
562 tmp = chan_rearrange[chan];
563 out_chan = &AAS_channels[tmp];
566 /* Tidy up after arpeggio */
567 effect = mod_chan->effect;
570 tmp = mod_chan->note;
572 out_chan->frequency = AAS_MOD_period_conv_table[AAS_period_table[mod_samp[mod_chan->samp_num].finetune][tmp - 1]];
573 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
575 AAS_changed[output] = AAS_TRUE;
580 dat = *mod_chan->pattern++;
581 samp_num = (dat >> 24) - 1;
582 period = (dat >> 12) & 0xfff;
583 effect = dat & 0xfff;
586 mod_chan->samp_num = samp_num;
587 mod_chan->volume = tmp = mod_samp[samp_num].volume;
588 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
590 AAS_changed[output] = AAS_TRUE;
592 samp_num = mod_chan->samp_num;
597 const struct AAS_ModSample *samp = &mod_samp[samp_num];
599 mod_chan->note = period;
600 period = AAS_period_table[samp->finetune][period - 1];
602 if((effect > 0xed0) && (effect < 0xee0)) /* delay sample */
604 mod_chan->period = period;
605 mod_chan->trigger = (effect & 0xf) - 1;
609 if((tmp != 0x3) && (tmp != 0x5)) {
610 int repeat = samp->repeat;
611 int length = samp->length;
612 const AAS_s8 *data = AAS_SampleData + samp->data;
614 mod_chan->samp_start = data;
615 out_chan->pos = data;
616 out_chan->pos_fraction = 0;
617 mod_chan->period = period;
619 out_chan->loop_length = 0;
621 out_chan->loop_length = ((AAS_u32) (length - repeat)) << 1;
622 out_chan->end = data + (length << 1);
623 out_chan->frequency = AAS_MOD_period_conv_table[period];
624 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
625 out_chan->active = AAS_TRUE;
627 AAS_changed[output] = AAS_TRUE;
634 switch (effect >> 8) {
635 case 0xf: /* set speed */
636 speed = effect & 0xff;
641 AAS_mod_speed = speed;
643 /*AAS_mod_tempo = (((1<<15)*AAS_mod_bpm*24)/(3000*AAS_mod_speed))<<13; // use LUT */
646 /*AAS_mod_tempo = AAS_DivTable[AAS_mod_speed]*AAS_mod_bpm*33; */
647 AAS_mod_tempo = AAS_DivTable[AAS_mod_speed] * AAS_mod_bpm;
649 effect = 0; /* No need to process this effect again */
652 case 0xe: /* extended effects */
653 switch (effect & 0xf0) {
654 case 0x00: /* set filter (used to send messages to code instead) */
655 AAS_mod_last_filter_value = effect & 0xf;
656 effect = 0; /* No need to process this effect again */
659 case 0x10: /* fine slide up */
660 tmp = mod_chan->period - (effect & 0xf);
663 mod_chan->period = tmp;
664 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
665 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
666 effect = 0; /* No need to process this effect again */
668 AAS_changed[output] = AAS_TRUE;
671 case 0x20: /* fine slide down */
672 tmp = mod_chan->period + (effect & 0xf);
675 mod_chan->period = tmp;
676 out_chan->frequency = AAS_MOD_period_conv_table[tmp];
677 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
678 effect = 0; /* No need to process this effect again */
680 AAS_changed[output] = AAS_TRUE;
683 case 0x60: /* set/jump to loop */
686 if(AAS_mod_loop_counter)
687 --AAS_mod_loop_counter;
689 AAS_mod_loop_counter = tmp;
691 if(AAS_mod_loop_counter) {
693 struct AAS_MOD_Channel
694 *mod_chan2 = AAS_mod_chan;
696 for(i = 0; i < num_chans; ++i) {
697 mod_chan2->pattern = (AAS_u32 *)(AAS_PatternData + (((int)AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][i]) << 8));
698 mod_chan2-> pattern += AAS_mod_loop_start;
701 AAS_mod_line_num = AAS_mod_loop_start;
704 AAS_mod_loop_start = AAS_mod_line_num;
706 effect = 0; /* No need to process this effect again */
709 case 0x90: /* retrigger sample */
710 mod_chan->trigger = (effect & 0xf) - 1;
713 case 0xa0: /* fine volume slide up */
714 tmp = mod_chan->volume;
718 mod_chan->volume = tmp;
719 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
720 effect = 0; /* No need to process this effect again */
722 AAS_changed[output] = AAS_TRUE;
725 case 0xb0: /* fine volume slide down */
726 tmp = mod_chan->volume;
730 mod_chan->volume = tmp;
731 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
732 effect = 0; /* No need to process this effect again */
734 AAS_changed[output] = AAS_TRUE;
737 case 0xc0: /* note cut */
738 if((effect & 0xf) == 0) {
740 out_chan->active = AAS_FALSE;
741 AAS_changed[output] = AAS_TRUE;
745 case 0xe0: /* pattern delay */
746 AAS_mod_timer -= (effect & 0xf) * 0x7d0000;
747 effect = 0; /* No need to process this effect again */
755 case 0xd: /* pattern break */
756 /*jump_ahead = (((effect>>4)&0xf)*10)+(effect&0xf); */
757 jump_ahead = effect & 0xff;
758 effect = 0; /* No need to process this effect again */
761 case 0xc: /* set volume */
762 mod_chan->volume = tmp = effect & 0xff;
763 out_chan->volume = (tmp * AAS_mod_overall_volume) >> AAS_volscale;
764 effect = 0; /* No need to process this effect again */
766 AAS_changed[output] = AAS_TRUE;
769 case 0xb: /* position jump */
770 jump_song_pos = effect & 0xff;
771 effect = 0; /* No need to process this effect again */
774 case 0x9: /* set sample offset */
777 const AAS_s8 *new_pos = mod_chan->samp_start + (tmp << 8);
779 if(new_pos >= out_chan->end) {
780 out_chan->active = AAS_FALSE;
782 AAS_changed[output] = AAS_TRUE;
784 out_chan->pos = new_pos;
786 effect = 0; /* No need to process this effect again */
789 case 0x7: /* tremolo */
791 mod_chan->tremolo_rate = (effect & 0xf0) >> 4;
793 mod_chan->tremolo_depth = effect & 0xf;
795 mod_chan->tremolo_pos = 0;
798 case 0x4: /* vibrato */
800 mod_chan->vibrato_rate = (effect & 0xf0) >> 4;
802 mod_chan->vibrato_depth = effect & 0xf;
804 mod_chan->vibrato_pos = 0;
807 case 0x3: /* tone portamento */
810 mod_chan->slide_rate = tmp;
813 mod_chan->slide_target_period = period;
814 else if(mod_chan->slide_target_period == 0)
818 case 0x0: /* possible arpeggio */
820 if(tmp) /* definite arpeggio */
822 tmp = mod_chan->note;
823 mod_chan->arpeggio_pos = 0;
825 out_chan->frequency = AAS_MOD_period_conv_table[AAS_period_table[mod_samp[mod_chan->samp_num].finetune][tmp - 1]];
826 out_chan->delta = AAS_Min(4095, ((out_chan->frequency * AAS_mix_scale) + 32768) >> 16);
828 AAS_changed[output] = AAS_TRUE;
834 /*printf_special( "effect:%p period:%d samp:%d\n", effect, period, samp_num ); */
839 mod_chan->effect = effect;
841 active_effects = AAS_TRUE;
845 AAS_mod_active_effects = active_effects;
847 if(jump_ahead >= 0) {
848 AAS_mod_loop_start = 0;
850 if(AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][0] == -1) {
851 AAS_mod_looped = AAS_TRUE;
852 AAS_mod_song_pos = 0;
853 mod_chan = AAS_mod_chan;
854 for(chan = num_chans; chan > 0; --chan) {
855 mod_chan->slide_target_period = 0;
860 mod_chan = AAS_mod_chan;
861 for(chan = 0; chan < num_chans; ++chan) {
862 mod_chan->pattern = (AAS_u32 *) (AAS_PatternData + (((int)AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][chan]) << 8));
863 mod_chan->pattern += jump_ahead;
866 AAS_mod_line_num = jump_ahead;
867 } else if(jump_song_pos >= 0) {
868 AAS_mod_loop_start = 0;
869 if(jump_song_pos < 128) {
870 AAS_mod_song_pos = jump_song_pos;
871 if(AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][0] == -1) {
872 AAS_mod_looped = AAS_TRUE;
873 mod_chan = AAS_mod_chan;
874 for(chan = num_chans; chan > 0; --chan) {
875 mod_chan->slide_target_period = 0;
878 AAS_mod_song_pos = 0;
881 AAS_mod_looped = AAS_TRUE;
882 mod_chan = AAS_mod_chan;
883 for(chan = num_chans; chan > 0; --chan) {
884 mod_chan->slide_target_period = 0;
887 AAS_mod_song_pos = 0;
890 mod_chan = AAS_mod_chan;
891 for(chan = 0; chan < num_chans; ++chan) {
892 mod_chan->pattern = (AAS_u32*)(AAS_PatternData + (((int)AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][chan]) << 8));
895 AAS_mod_line_num = 0;
898 if(AAS_mod_line_num > 63) {
899 AAS_mod_line_num = 0;
900 AAS_mod_loop_start = 0;
902 if(AAS_mod_next_song_pos == -1) {
905 AAS_mod_song_pos = AAS_mod_next_song_pos;
906 AAS_mod_next_song_pos = -1;
909 if(AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][0] == -1) {
910 AAS_mod_looped = AAS_TRUE;
911 mod_chan = AAS_mod_chan;
912 for(chan = num_chans; chan > 0; --chan) {
913 mod_chan->slide_target_period = 0;
916 AAS_mod_song_pos = AAS_RestartPos[AAS_mod_num];
919 mod_chan = AAS_mod_chan;
920 for(chan = 0; chan < num_chans; ++chan) {
921 mod_chan->pattern = (AAS_u32*)(AAS_PatternData + (((int)AAS_Sequence[AAS_mod_num][AAS_mod_song_pos][chan]) << 8));