xref: /btstack/3rd-party/hxcmod-player/hxcmod.c (revision c5456c210e522243d40aa426f433c0a266615d64)
1a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
2a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
3a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
4a4cd9b30SMilanka Ringwald //-----------H----H--X----X-----CCCCC----22222----0000-----0000------11----------//
5a4cd9b30SMilanka Ringwald //----------H----H----X-X-----C--------------2---0----0---0----0--1--1-----------//
6a4cd9b30SMilanka Ringwald //---------HHHHHH-----X------C----------22222---0----0---0----0-----1------------//
7a4cd9b30SMilanka Ringwald //--------H----H----X--X----C----------2-------0----0---0----0-----1-------------//
8a4cd9b30SMilanka Ringwald //-------H----H---X-----X---CCCCC-----222222----0000-----0000----1111------------//
9a4cd9b30SMilanka Ringwald //-------------------------------------------------------------------------------//
10a4cd9b30SMilanka Ringwald //----------------------------------------------------- http://hxc2001.free.fr --//
11a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
12a4cd9b30SMilanka Ringwald // File : hxcmod.c
13a4cd9b30SMilanka Ringwald // Contains: a tiny mod player
14a4cd9b30SMilanka Ringwald //
15a4cd9b30SMilanka Ringwald // Written by: Jean Fran�ois DEL NERO
16a4cd9b30SMilanka Ringwald //
17a4cd9b30SMilanka Ringwald // You are free to do what you want with this code.
18a4cd9b30SMilanka Ringwald // A credit is always appreciated if you include it into your prod :)
19a4cd9b30SMilanka Ringwald //
20a4cd9b30SMilanka Ringwald // This file include some parts of the Noisetracker/Soundtracker/Protracker
21a4cd9b30SMilanka Ringwald // Module Format documentation written by Andrew Scott (Adrenalin Software)
22a4cd9b30SMilanka Ringwald // (modformat.txt)
23a4cd9b30SMilanka Ringwald //
24a4cd9b30SMilanka Ringwald // The core (hxcmod.c/hxcmod.h) is designed to have the least external dependency.
25a4cd9b30SMilanka Ringwald // So it should be usable on almost all OS and systems.
26a4cd9b30SMilanka Ringwald // Please also note that no dynamic allocation is done into the HxCMOD core.
27a4cd9b30SMilanka Ringwald //
28a4cd9b30SMilanka Ringwald // Change History (most recent first):
29a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
30a4cd9b30SMilanka Ringwald // HxCMOD Core API:
31a4cd9b30SMilanka Ringwald // -------------------------------------------
32a4cd9b30SMilanka Ringwald // int  hxcmod_init(modcontext * modctx)
33a4cd9b30SMilanka Ringwald //
34a4cd9b30SMilanka Ringwald // - Initialize the modcontext buffer. Must be called before doing anything else.
35a4cd9b30SMilanka Ringwald //   Return 1 if success. 0 in case of error.
36a4cd9b30SMilanka Ringwald // -------------------------------------------
37a4cd9b30SMilanka Ringwald // int  hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size )
38a4cd9b30SMilanka Ringwald //
39a4cd9b30SMilanka Ringwald // - "Load" a MOD from memory (from "mod_data" with size "mod_data_size").
40a4cd9b30SMilanka Ringwald //   Return 1 if success. 0 in case of error.
41a4cd9b30SMilanka Ringwald // -------------------------------------------
42a4cd9b30SMilanka Ringwald // void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf )
43a4cd9b30SMilanka Ringwald //
44a4cd9b30SMilanka Ringwald // - Generate and return the next samples chunk to outbuffer.
45a4cd9b30SMilanka Ringwald //   nbsample specify the number of stereo 16bits samples you want.
46a4cd9b30SMilanka Ringwald //   The output format is signed 44100Hz 16-bit Stereo PCM samples.
47a4cd9b30SMilanka Ringwald //   The output buffer size in byte must be equal to ( nbsample * 2 * 2 ).
48a4cd9b30SMilanka Ringwald //   The optional trkbuf parameter can be used to get detailed status of the player. Put NULL/0 is unused.
49a4cd9b30SMilanka Ringwald // -------------------------------------------
50a4cd9b30SMilanka Ringwald // void hxcmod_unload( modcontext * modctx )
51a4cd9b30SMilanka Ringwald // - "Unload" / clear the player status.
52a4cd9b30SMilanka Ringwald // -------------------------------------------
53a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
54a4cd9b30SMilanka Ringwald 
55a4cd9b30SMilanka Ringwald #include "hxcmod.h"
56a4cd9b30SMilanka Ringwald 
57a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
58a4cd9b30SMilanka Ringwald 
59a4cd9b30SMilanka Ringwald // Effects list
60a4cd9b30SMilanka Ringwald #define EFFECT_ARPEGGIO              0x0 // Supported
61a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_UP         0x1 // Supported
62a4cd9b30SMilanka Ringwald #define EFFECT_PORTAMENTO_DOWN       0x2 // Supported
63a4cd9b30SMilanka Ringwald #define EFFECT_TONE_PORTAMENTO       0x3 // Supported
64a4cd9b30SMilanka Ringwald #define EFFECT_VIBRATO               0x4 // Supported
65a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TONEPORTA    0x5 // Supported
66a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_VIBRATO      0x6 // Supported
67a4cd9b30SMilanka Ringwald #define EFFECT_VOLSLIDE_TREMOLO      0x7 // - TO BE DONE -
68a4cd9b30SMilanka Ringwald #define EFFECT_SET_PANNING           0x8 // - TO BE DONE -
69a4cd9b30SMilanka Ringwald #define EFFECT_SET_OFFSET            0x9 // Supported
70a4cd9b30SMilanka Ringwald #define EFFECT_VOLUME_SLIDE          0xA // Supported
71a4cd9b30SMilanka Ringwald #define EFFECT_JUMP_POSITION         0xB // Supported
72a4cd9b30SMilanka Ringwald #define EFFECT_SET_VOLUME            0xC // Supported
73a4cd9b30SMilanka Ringwald #define EFFECT_PATTERN_BREAK         0xD // Supported
74a4cd9b30SMilanka Ringwald 
75a4cd9b30SMilanka Ringwald #define EFFECT_EXTENDED              0xE
76a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_UP       0x1 // Supported
77a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_PORTA_DOWN     0x2 // Supported
78a4cd9b30SMilanka Ringwald #define EFFECT_E_GLISSANDO_CTRL      0x3 // - TO BE DONE -
79a4cd9b30SMilanka Ringwald #define EFFECT_E_VIBRATO_WAVEFORM    0x4 // - TO BE DONE -
80a4cd9b30SMilanka Ringwald #define EFFECT_E_SET_FINETUNE        0x5 // - TO BE DONE -
81a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_LOOP        0x6 // Supported
82a4cd9b30SMilanka Ringwald #define EFFECT_E_TREMOLO_WAVEFORM    0x7 // - TO BE DONE -
83a4cd9b30SMilanka Ringwald #define EFFECT_E_SET_PANNING_2       0x8 // - TO BE DONE -
84a4cd9b30SMilanka Ringwald #define EFFECT_E_RETRIGGER_NOTE      0x9 // - TO BE DONE -
85a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_UP    0xA // Supported
86a4cd9b30SMilanka Ringwald #define EFFECT_E_FINE_VOLSLIDE_DOWN  0xB // Supported
87a4cd9b30SMilanka Ringwald #define EFFECT_E_NOTE_CUT            0xC // Supported
88a4cd9b30SMilanka Ringwald #define EFFECT_E_NOTE_DELAY          0xD // - TO BE DONE -
89a4cd9b30SMilanka Ringwald #define EFFECT_E_PATTERN_DELAY       0xE // Supported
90a4cd9b30SMilanka Ringwald #define EFFECT_E_INVERT_LOOP         0xF // - TO BE DONE -
91a4cd9b30SMilanka Ringwald #define EFFECT_SET_SPEED             0xF0 // Supported
92a4cd9b30SMilanka Ringwald #define EFFECT_SET_TEMPO             0xF2 // Supported
93a4cd9b30SMilanka Ringwald 
94a4cd9b30SMilanka Ringwald #define PERIOD_TABLE_LENGTH  MAXNOTES
95a4cd9b30SMilanka Ringwald #define FULL_PERIOD_TABLE_LENGTH  ( PERIOD_TABLE_LENGTH * 8 )
96a4cd9b30SMilanka Ringwald 
97a4cd9b30SMilanka Ringwald static const short periodtable[]=
98a4cd9b30SMilanka Ringwald {
99a4cd9b30SMilanka Ringwald 	27392, 25856, 24384, 23040, 21696, 20480, 19328, 18240, 17216, 16256, 15360, 14496,
100a4cd9b30SMilanka Ringwald 	13696, 12928, 12192, 11520, 10848, 10240,  9664,  9120,  8606,  8128,  7680,  7248,
101a4cd9b30SMilanka Ringwald 	 6848,  6464,  6096,  5760,  5424,  5120,  4832,  4560,  4304,  4064,  3840,  3624,
102a4cd9b30SMilanka Ringwald 	 3424,  3232,  3048,  2880,  2712,  2560,  2416,  2280,  2152,  2032,  1920,  1812,
103a4cd9b30SMilanka Ringwald 	 1712,  1616,  1524,  1440,  1356,  1280,  1208,  1140,  1076,  1016,   960,   906,
104a4cd9b30SMilanka Ringwald 	  856,   808,   762,   720,   678,   640,   604,   570,   538,   508,   480,   453,
105a4cd9b30SMilanka Ringwald 	  428,   404,   381,   360,   339,   320,   302,   285,   269,   254,   240,   226,
106a4cd9b30SMilanka Ringwald 	  214,   202,   190,   180,   170,   160,   151,   143,   135,   127,   120,   113,
107a4cd9b30SMilanka Ringwald 	  107,   101,    95,    90,    85,    80,    75,    71,    67,    63,    60,    56,
108a4cd9b30SMilanka Ringwald 	   53,    50,    47,    45,    42,    40,    37,    35,    33,    31,    30,    28,
109a4cd9b30SMilanka Ringwald 	   27,    25,    24,    22,    21,    20,    19,    18,    17,    16,    15,    14,
110a4cd9b30SMilanka Ringwald 	   13,    13,    12,    11,    11,    10,     9,     9,     8,     8,     7,     7
111a4cd9b30SMilanka Ringwald };
112a4cd9b30SMilanka Ringwald 
113a4cd9b30SMilanka Ringwald static const short sintable[]={
114a4cd9b30SMilanka Ringwald 	  0,  24,  49,  74,  97, 120, 141,161,
115a4cd9b30SMilanka Ringwald 	180, 197, 212, 224, 235, 244, 250,253,
116a4cd9b30SMilanka Ringwald 	255, 253, 250, 244, 235, 224, 212,197,
117a4cd9b30SMilanka Ringwald 	180, 161, 141, 120,  97,  74,  49, 24
118a4cd9b30SMilanka Ringwald };
119a4cd9b30SMilanka Ringwald 
120a4cd9b30SMilanka Ringwald typedef struct modtype_
121a4cd9b30SMilanka Ringwald {
122a4cd9b30SMilanka Ringwald 	unsigned char signature[5];
123a4cd9b30SMilanka Ringwald 	int numberofchannels;
124a4cd9b30SMilanka Ringwald }modtype;
125a4cd9b30SMilanka Ringwald 
126a4cd9b30SMilanka Ringwald modtype modlist[]=
127a4cd9b30SMilanka Ringwald {
128a4cd9b30SMilanka Ringwald 	{ "M!K!",4},
129a4cd9b30SMilanka Ringwald 	{ "M.K.",4},
130a4cd9b30SMilanka Ringwald 	{ "FLT4",4},
131a4cd9b30SMilanka Ringwald 	{ "FLT8",8},
132a4cd9b30SMilanka Ringwald 	{ "4CHN",4},
133a4cd9b30SMilanka Ringwald 	{ "6CHN",6},
134a4cd9b30SMilanka Ringwald 	{ "8CHN",8},
135a4cd9b30SMilanka Ringwald 	{ "10CH",10},
136a4cd9b30SMilanka Ringwald 	{ "12CH",12},
137a4cd9b30SMilanka Ringwald 	{ "14CH",14},
138a4cd9b30SMilanka Ringwald 	{ "16CH",16},
139a4cd9b30SMilanka Ringwald 	{ "18CH",18},
140a4cd9b30SMilanka Ringwald 	{ "20CH",20},
141a4cd9b30SMilanka Ringwald 	{ "22CH",22},
142a4cd9b30SMilanka Ringwald 	{ "24CH",24},
143a4cd9b30SMilanka Ringwald 	{ "26CH",26},
144a4cd9b30SMilanka Ringwald 	{ "28CH",28},
145a4cd9b30SMilanka Ringwald 	{ "30CH",30},
146a4cd9b30SMilanka Ringwald 	{ "32CH",32},
147a4cd9b30SMilanka Ringwald 	{ "",0}
148a4cd9b30SMilanka Ringwald };
149a4cd9b30SMilanka Ringwald 
150a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
151a4cd9b30SMilanka Ringwald 
152a4cd9b30SMilanka Ringwald static void memcopy( void * dest, void *source, unsigned long size )
153a4cd9b30SMilanka Ringwald {
154a4cd9b30SMilanka Ringwald 	unsigned long i;
155a4cd9b30SMilanka Ringwald 	unsigned char * d,*s;
156a4cd9b30SMilanka Ringwald 
157a4cd9b30SMilanka Ringwald 	d=(unsigned char*)dest;
158a4cd9b30SMilanka Ringwald 	s=(unsigned char*)source;
159a4cd9b30SMilanka Ringwald 	for(i=0;i<size;i++)
160a4cd9b30SMilanka Ringwald 	{
161a4cd9b30SMilanka Ringwald 		d[i]=s[i];
162a4cd9b30SMilanka Ringwald 	}
163a4cd9b30SMilanka Ringwald }
164a4cd9b30SMilanka Ringwald 
165a4cd9b30SMilanka Ringwald static void memclear( void * dest, unsigned char value, unsigned long size )
166a4cd9b30SMilanka Ringwald {
167a4cd9b30SMilanka Ringwald 	unsigned long i;
168a4cd9b30SMilanka Ringwald 	unsigned char * d;
169a4cd9b30SMilanka Ringwald 
170a4cd9b30SMilanka Ringwald 	d=(unsigned char*)dest;
171a4cd9b30SMilanka Ringwald 	for(i=0;i<size;i++)
172a4cd9b30SMilanka Ringwald 	{
173a4cd9b30SMilanka Ringwald 		d[i]=value;
174a4cd9b30SMilanka Ringwald 	}
175a4cd9b30SMilanka Ringwald }
176a4cd9b30SMilanka Ringwald 
177a4cd9b30SMilanka Ringwald static int memcompare( unsigned char * buf1, unsigned char * buf2, unsigned int size )
178a4cd9b30SMilanka Ringwald {
179a4cd9b30SMilanka Ringwald 	unsigned int i;
180a4cd9b30SMilanka Ringwald 
181a4cd9b30SMilanka Ringwald 	i = 0;
182a4cd9b30SMilanka Ringwald 
183a4cd9b30SMilanka Ringwald 	while(i<size)
184a4cd9b30SMilanka Ringwald 	{
185a4cd9b30SMilanka Ringwald 		if(buf1[i] != buf2[i])
186a4cd9b30SMilanka Ringwald 		{
187a4cd9b30SMilanka Ringwald 			return 0;
188a4cd9b30SMilanka Ringwald 		}
189a4cd9b30SMilanka Ringwald 		i++;
190a4cd9b30SMilanka Ringwald 	}
191a4cd9b30SMilanka Ringwald 
192a4cd9b30SMilanka Ringwald 	return 1;
193a4cd9b30SMilanka Ringwald }
194a4cd9b30SMilanka Ringwald 
195a4cd9b30SMilanka Ringwald static int getnote( modcontext * mod, unsigned short period, int finetune )
196a4cd9b30SMilanka Ringwald {
197*c5456c21SMilanka Ringwald 	(void) finetune;
198a4cd9b30SMilanka Ringwald 	int i;
199a4cd9b30SMilanka Ringwald 
200a4cd9b30SMilanka Ringwald 	for(i = 0; i < FULL_PERIOD_TABLE_LENGTH; i++)
201a4cd9b30SMilanka Ringwald 	{
202a4cd9b30SMilanka Ringwald 		if(period >= mod->fullperiod[i])
203a4cd9b30SMilanka Ringwald 		{
204a4cd9b30SMilanka Ringwald 			return i;
205a4cd9b30SMilanka Ringwald 		}
206a4cd9b30SMilanka Ringwald 	}
207a4cd9b30SMilanka Ringwald 
208a4cd9b30SMilanka Ringwald 	return MAXNOTES;
209a4cd9b30SMilanka Ringwald }
210a4cd9b30SMilanka Ringwald 
211a4cd9b30SMilanka Ringwald static void worknote( note * nptr, channel * cptr,char t,modcontext * mod )
212a4cd9b30SMilanka Ringwald {
213*c5456c21SMilanka Ringwald 	(void) t;
214a4cd9b30SMilanka Ringwald 	muint sample, period, effect, operiod;
215a4cd9b30SMilanka Ringwald 	muint curnote, arpnote;
216a4cd9b30SMilanka Ringwald 
217a4cd9b30SMilanka Ringwald 	sample = (nptr->sampperiod & 0xF0) | (nptr->sampeffect >> 4);
218a4cd9b30SMilanka Ringwald 	period = ((nptr->sampperiod & 0xF) << 8) | nptr->period;
219a4cd9b30SMilanka Ringwald 	effect = ((nptr->sampeffect & 0xF) << 8) | nptr->effect;
220a4cd9b30SMilanka Ringwald 
221a4cd9b30SMilanka Ringwald 	operiod = cptr->period;
222a4cd9b30SMilanka Ringwald 
223a4cd9b30SMilanka Ringwald 	if ( period || sample )
224a4cd9b30SMilanka Ringwald 	{
225a4cd9b30SMilanka Ringwald 		if( sample && sample<32 )
226a4cd9b30SMilanka Ringwald 		{
227a4cd9b30SMilanka Ringwald 			cptr->sampnum = sample - 1;
228a4cd9b30SMilanka Ringwald 		}
229a4cd9b30SMilanka Ringwald 
230a4cd9b30SMilanka Ringwald 		if( period || sample )
231a4cd9b30SMilanka Ringwald 		{
232a4cd9b30SMilanka Ringwald 			cptr->sampdata =(char *) mod->sampledata[cptr->sampnum];
233a4cd9b30SMilanka Ringwald 			cptr->length = mod->song.samples[cptr->sampnum].length;
234a4cd9b30SMilanka Ringwald 			cptr->reppnt = mod->song.samples[cptr->sampnum].reppnt;
235a4cd9b30SMilanka Ringwald 			cptr->replen = mod->song.samples[cptr->sampnum].replen;
236a4cd9b30SMilanka Ringwald 
237a4cd9b30SMilanka Ringwald 			cptr->finetune = (mod->song.samples[cptr->sampnum].finetune)&0xF;
238a4cd9b30SMilanka Ringwald 
239a4cd9b30SMilanka Ringwald 			if(effect>>8!=4 && effect>>8!=6)
240a4cd9b30SMilanka Ringwald 			{
241a4cd9b30SMilanka Ringwald 				cptr->vibraperiod=0;
242a4cd9b30SMilanka Ringwald 				cptr->vibrapointeur=0;
243a4cd9b30SMilanka Ringwald 			}
244a4cd9b30SMilanka Ringwald 		}
245a4cd9b30SMilanka Ringwald 
246a4cd9b30SMilanka Ringwald 		if( (sample != 0) && ( (effect>>8) != EFFECT_VOLSLIDE_TONEPORTA ) )
247a4cd9b30SMilanka Ringwald 		{
248a4cd9b30SMilanka Ringwald 			cptr->volume = mod->song.samples[cptr->sampnum].volume;
249a4cd9b30SMilanka Ringwald 			cptr->volumeslide = 0;
250a4cd9b30SMilanka Ringwald 		}
251a4cd9b30SMilanka Ringwald 
252a4cd9b30SMilanka Ringwald 		if( ( (effect>>8) != EFFECT_TONE_PORTAMENTO && (effect>>8)!=EFFECT_VOLSLIDE_TONEPORTA) )
253a4cd9b30SMilanka Ringwald 		{
254a4cd9b30SMilanka Ringwald 			if (period!=0)
255a4cd9b30SMilanka Ringwald 				cptr->samppos = 0;
256a4cd9b30SMilanka Ringwald 		}
257a4cd9b30SMilanka Ringwald 
258a4cd9b30SMilanka Ringwald 		cptr->decalperiod=0;
259a4cd9b30SMilanka Ringwald 		if( period )
260a4cd9b30SMilanka Ringwald 		{
261a4cd9b30SMilanka Ringwald 			if(cptr->finetune)
262a4cd9b30SMilanka Ringwald 			{
263a4cd9b30SMilanka Ringwald 				if( cptr->finetune <= 7 )
264a4cd9b30SMilanka Ringwald 				{
265a4cd9b30SMilanka Ringwald 					period = mod->fullperiod[getnote(mod,period,0) + cptr->finetune];
266a4cd9b30SMilanka Ringwald 				}
267a4cd9b30SMilanka Ringwald 				else
268a4cd9b30SMilanka Ringwald 				{
269a4cd9b30SMilanka Ringwald 					period = mod->fullperiod[getnote(mod,period,0) - (16 - (cptr->finetune)) ];
270a4cd9b30SMilanka Ringwald 				}
271a4cd9b30SMilanka Ringwald 			}
272a4cd9b30SMilanka Ringwald 
273a4cd9b30SMilanka Ringwald 			cptr->period = period;
274a4cd9b30SMilanka Ringwald 		}
275a4cd9b30SMilanka Ringwald 
276a4cd9b30SMilanka Ringwald 	}
277a4cd9b30SMilanka Ringwald 
278a4cd9b30SMilanka Ringwald 	cptr->effect = 0;
279a4cd9b30SMilanka Ringwald 	cptr->parameffect = 0;
280a4cd9b30SMilanka Ringwald 	cptr->effect_code = effect;
281a4cd9b30SMilanka Ringwald 
282a4cd9b30SMilanka Ringwald 	switch (effect >> 8)
283a4cd9b30SMilanka Ringwald 	{
284a4cd9b30SMilanka Ringwald 		case EFFECT_ARPEGGIO:
285a4cd9b30SMilanka Ringwald 			/*
286a4cd9b30SMilanka Ringwald 			[0]: Arpeggio
287a4cd9b30SMilanka Ringwald 			Where [0][x][y] means "play note, note+x semitones, note+y
288a4cd9b30SMilanka Ringwald 			semitones, then return to original note". The fluctuations are
289a4cd9b30SMilanka Ringwald 			carried out evenly spaced in one pattern division. They are usually
290a4cd9b30SMilanka Ringwald 			used to simulate chords, but this doesn't work too well. They are
291a4cd9b30SMilanka Ringwald 			also used to produce heavy vibrato. A major chord is when x=4, y=7.
292a4cd9b30SMilanka Ringwald 			A minor chord is when x=3, y=7.
293a4cd9b30SMilanka Ringwald 			*/
294a4cd9b30SMilanka Ringwald 
295a4cd9b30SMilanka Ringwald 			if(effect&0xff)
296a4cd9b30SMilanka Ringwald 			{
297a4cd9b30SMilanka Ringwald 				cptr->effect = EFFECT_ARPEGGIO;
298a4cd9b30SMilanka Ringwald 				cptr->parameffect = effect&0xff;
299a4cd9b30SMilanka Ringwald 
300a4cd9b30SMilanka Ringwald 				cptr->ArpIndex = 0;
301a4cd9b30SMilanka Ringwald 
302a4cd9b30SMilanka Ringwald 				curnote = getnote(mod,cptr->period,cptr->finetune);
303a4cd9b30SMilanka Ringwald 
304a4cd9b30SMilanka Ringwald 				cptr->Arpperiods[0] = cptr->period;
305a4cd9b30SMilanka Ringwald 
306a4cd9b30SMilanka Ringwald 				arpnote = curnote + (((cptr->parameffect>>4)&0xF)*8);
307a4cd9b30SMilanka Ringwald 				if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
308a4cd9b30SMilanka Ringwald 					arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
309a4cd9b30SMilanka Ringwald 
310a4cd9b30SMilanka Ringwald 				cptr->Arpperiods[1] = mod->fullperiod[arpnote];
311a4cd9b30SMilanka Ringwald 
312a4cd9b30SMilanka Ringwald 				arpnote = curnote + (((cptr->parameffect)&0xF)*8);
313a4cd9b30SMilanka Ringwald 				if( arpnote >= FULL_PERIOD_TABLE_LENGTH )
314a4cd9b30SMilanka Ringwald 					arpnote = FULL_PERIOD_TABLE_LENGTH - 1;
315a4cd9b30SMilanka Ringwald 
316a4cd9b30SMilanka Ringwald 				cptr->Arpperiods[2] = mod->fullperiod[arpnote];
317a4cd9b30SMilanka Ringwald 			}
318a4cd9b30SMilanka Ringwald 		break;
319a4cd9b30SMilanka Ringwald 
320a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_UP:
321a4cd9b30SMilanka Ringwald 			/*
322a4cd9b30SMilanka Ringwald 			[1]: Slide up
323a4cd9b30SMilanka Ringwald 			Where [1][x][y] means "smoothly decrease the period of current
324a4cd9b30SMilanka Ringwald 			sample by x*16+y after each tick in the division". The
325a4cd9b30SMilanka Ringwald 			ticks/division are set with the 'set speed' effect (see below). If
326a4cd9b30SMilanka Ringwald 			the period of the note being played is z, then the final period
327a4cd9b30SMilanka Ringwald 			will be z - (x*16 + y)*(ticks - 1). As the slide rate depends on
328a4cd9b30SMilanka Ringwald 			the speed, changing the speed will change the slide. You cannot
329a4cd9b30SMilanka Ringwald 			slide beyond the note B3 (period 113).
330a4cd9b30SMilanka Ringwald 			*/
331a4cd9b30SMilanka Ringwald 
332a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_PORTAMENTO_UP;
333a4cd9b30SMilanka Ringwald 			cptr->parameffect = effect&0xff;
334a4cd9b30SMilanka Ringwald 		break;
335a4cd9b30SMilanka Ringwald 
336a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_DOWN:
337a4cd9b30SMilanka Ringwald 			/*
338a4cd9b30SMilanka Ringwald 			[2]: Slide down
339a4cd9b30SMilanka Ringwald 			Where [2][x][y] means "smoothly increase the period of current
340a4cd9b30SMilanka Ringwald 			sample by x*16+y after each tick in the division". Similar to [1],
341a4cd9b30SMilanka Ringwald 			but lowers the pitch. You cannot slide beyond the note C1 (period
342a4cd9b30SMilanka Ringwald 			856).
343a4cd9b30SMilanka Ringwald 			*/
344a4cd9b30SMilanka Ringwald 
345a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_PORTAMENTO_DOWN;
346a4cd9b30SMilanka Ringwald 			cptr->parameffect = effect&0xff;
347a4cd9b30SMilanka Ringwald 		break;
348a4cd9b30SMilanka Ringwald 
349a4cd9b30SMilanka Ringwald 		case EFFECT_TONE_PORTAMENTO:
350a4cd9b30SMilanka Ringwald 			/*
351a4cd9b30SMilanka Ringwald 			[3]: Slide to note
352a4cd9b30SMilanka Ringwald 			Where [3][x][y] means "smoothly change the period of current sample
353a4cd9b30SMilanka Ringwald 			by x*16+y after each tick in the division, never sliding beyond
354a4cd9b30SMilanka Ringwald 			current period". The period-length in this channel's division is a
355a4cd9b30SMilanka Ringwald 			parameter to this effect, and hence is not played. Sliding to a
356a4cd9b30SMilanka Ringwald 			note is similar to effects [1] and [2], but the slide will not go
357a4cd9b30SMilanka Ringwald 			beyond the given period, and the direction is implied by that
358a4cd9b30SMilanka Ringwald 			period. If x and y are both 0, then the old slide will continue.
359a4cd9b30SMilanka Ringwald 			*/
360a4cd9b30SMilanka Ringwald 
361a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_TONE_PORTAMENTO;
362a4cd9b30SMilanka Ringwald 			if( (effect&0xff) != 0 )
363a4cd9b30SMilanka Ringwald 			{
364a4cd9b30SMilanka Ringwald 				cptr->portaspeed = (short)(effect&0xff);
365a4cd9b30SMilanka Ringwald 			}
366a4cd9b30SMilanka Ringwald 
367a4cd9b30SMilanka Ringwald 			if(period!=0)
368a4cd9b30SMilanka Ringwald 			{
369a4cd9b30SMilanka Ringwald 				cptr->portaperiod = period;
370a4cd9b30SMilanka Ringwald 				cptr->period = operiod;
371a4cd9b30SMilanka Ringwald 			}
372a4cd9b30SMilanka Ringwald 		break;
373a4cd9b30SMilanka Ringwald 
374a4cd9b30SMilanka Ringwald 		case EFFECT_VIBRATO:
375a4cd9b30SMilanka Ringwald 			/*
376a4cd9b30SMilanka Ringwald 			[4]: Vibrato
377a4cd9b30SMilanka Ringwald 			Where [4][x][y] means "oscillate the sample pitch using a
378a4cd9b30SMilanka Ringwald 			particular waveform with amplitude y/16 semitones, such that (x *
379a4cd9b30SMilanka Ringwald 			ticks)/64 cycles occur in the division". The waveform is set using
380a4cd9b30SMilanka Ringwald 			effect [14][4]. By placing vibrato effects on consecutive
381a4cd9b30SMilanka Ringwald 			divisions, the vibrato effect can be maintained. If either x or y
382a4cd9b30SMilanka Ringwald 			are 0, then the old vibrato values will be used.
383a4cd9b30SMilanka Ringwald 			*/
384a4cd9b30SMilanka Ringwald 
385a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VIBRATO;
386a4cd9b30SMilanka Ringwald 			if( ( effect & 0x0F ) != 0 ) // Depth continue or change ?
387a4cd9b30SMilanka Ringwald 				cptr->vibraparam = (cptr->vibraparam & 0xF0) | ( effect & 0x0F );
388a4cd9b30SMilanka Ringwald 			if( ( effect & 0xF0 ) != 0 ) // Speed continue or change ?
389a4cd9b30SMilanka Ringwald 				cptr->vibraparam = (cptr->vibraparam & 0x0F) | ( effect & 0xF0 );
390a4cd9b30SMilanka Ringwald 
391a4cd9b30SMilanka Ringwald 		break;
392a4cd9b30SMilanka Ringwald 
393a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_TONEPORTA:
394a4cd9b30SMilanka Ringwald 			/*
395a4cd9b30SMilanka Ringwald 			[5]: Continue 'Slide to note', but also do Volume slide
396a4cd9b30SMilanka Ringwald 			Where [5][x][y] means "either slide the volume up x*(ticks - 1) or
397a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1), at the same time as continuing
398a4cd9b30SMilanka Ringwald 			the last 'Slide to note'". It is illegal for both x and y to be
399a4cd9b30SMilanka Ringwald 			non-zero. You cannot slide outside the volume range 0..64. The
400a4cd9b30SMilanka Ringwald 			period-length in this channel's division is a parameter to this
401a4cd9b30SMilanka Ringwald 			effect, and hence is not played.
402a4cd9b30SMilanka Ringwald 			*/
403a4cd9b30SMilanka Ringwald 
404a4cd9b30SMilanka Ringwald 			if( period != 0 )
405a4cd9b30SMilanka Ringwald 			{
406a4cd9b30SMilanka Ringwald 				cptr->portaperiod = period;
407a4cd9b30SMilanka Ringwald 				cptr->period = operiod;
408a4cd9b30SMilanka Ringwald 			}
409a4cd9b30SMilanka Ringwald 
410a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLSLIDE_TONEPORTA;
411a4cd9b30SMilanka Ringwald 			if( ( effect & 0xFF ) != 0 )
412a4cd9b30SMilanka Ringwald 				cptr->volumeslide = ( effect & 0xFF );
413a4cd9b30SMilanka Ringwald 
414a4cd9b30SMilanka Ringwald 		break;
415a4cd9b30SMilanka Ringwald 
416a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_VIBRATO:
417a4cd9b30SMilanka Ringwald 			/*
418a4cd9b30SMilanka Ringwald 			[6]: Continue 'Vibrato', but also do Volume slide
419a4cd9b30SMilanka Ringwald 			Where [6][x][y] means "either slide the volume up x*(ticks - 1) or
420a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1), at the same time as continuing
421a4cd9b30SMilanka Ringwald 			the last 'Vibrato'". It is illegal for both x and y to be non-zero.
422a4cd9b30SMilanka Ringwald 			You cannot slide outside the volume range 0..64.
423a4cd9b30SMilanka Ringwald 			*/
424a4cd9b30SMilanka Ringwald 
425a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLSLIDE_VIBRATO;
426a4cd9b30SMilanka Ringwald 			if( (effect & 0xFF) != 0 )
427a4cd9b30SMilanka Ringwald 				cptr->volumeslide = (effect & 0xFF);
428a4cd9b30SMilanka Ringwald 		break;
429a4cd9b30SMilanka Ringwald 
430a4cd9b30SMilanka Ringwald 		case EFFECT_SET_OFFSET:
431a4cd9b30SMilanka Ringwald 			/*
432a4cd9b30SMilanka Ringwald 			[9]: Set sample offset
433a4cd9b30SMilanka Ringwald 			Where [9][x][y] means "play the sample from offset x*4096 + y*256".
434a4cd9b30SMilanka Ringwald 			The offset is measured in words. If no sample is given, yet one is
435a4cd9b30SMilanka Ringwald 			still playing on this channel, it should be retriggered to the new
436a4cd9b30SMilanka Ringwald 			offset using the current volume.
437a4cd9b30SMilanka Ringwald 			*/
438a4cd9b30SMilanka Ringwald 
439a4cd9b30SMilanka Ringwald 			cptr->samppos = ((effect>>4) * 4096) + ((effect&0xF)*256);
440a4cd9b30SMilanka Ringwald 
441a4cd9b30SMilanka Ringwald 		break;
442a4cd9b30SMilanka Ringwald 
443a4cd9b30SMilanka Ringwald 		case EFFECT_VOLUME_SLIDE:
444a4cd9b30SMilanka Ringwald 			/*
445a4cd9b30SMilanka Ringwald 			[10]: Volume slide
446a4cd9b30SMilanka Ringwald 			Where [10][x][y] means "either slide the volume up x*(ticks - 1) or
447a4cd9b30SMilanka Ringwald 			slide the volume down y*(ticks - 1)". If both x and y are non-zero,
448a4cd9b30SMilanka Ringwald 			then the y value is ignored (assumed to be 0). You cannot slide
449a4cd9b30SMilanka Ringwald 			outside the volume range 0..64.
450a4cd9b30SMilanka Ringwald 			*/
451a4cd9b30SMilanka Ringwald 
452a4cd9b30SMilanka Ringwald 			cptr->effect = EFFECT_VOLUME_SLIDE;
453a4cd9b30SMilanka Ringwald 			cptr->volumeslide = (effect & 0xFF);
454a4cd9b30SMilanka Ringwald 		break;
455a4cd9b30SMilanka Ringwald 
456a4cd9b30SMilanka Ringwald 		case EFFECT_JUMP_POSITION:
457a4cd9b30SMilanka Ringwald 			/*
458a4cd9b30SMilanka Ringwald 			[11]: Position Jump
459a4cd9b30SMilanka Ringwald 			Where [11][x][y] means "stop the pattern after this division, and
460a4cd9b30SMilanka Ringwald 			continue the song at song-position x*16+y". This shifts the
461a4cd9b30SMilanka Ringwald 			'pattern-cursor' in the pattern table (see above). Legal values for
462a4cd9b30SMilanka Ringwald 			x*16+y are from 0 to 127.
463a4cd9b30SMilanka Ringwald 			*/
464a4cd9b30SMilanka Ringwald 
465a4cd9b30SMilanka Ringwald 			mod->tablepos = (effect & 0xFF);
466a4cd9b30SMilanka Ringwald 			if(mod->tablepos >= mod->song.length)
467a4cd9b30SMilanka Ringwald 				mod->tablepos = 0;
468a4cd9b30SMilanka Ringwald 			mod->patternpos = 0;
469a4cd9b30SMilanka Ringwald 			mod->jump_loop_effect = 1;
470a4cd9b30SMilanka Ringwald 
471a4cd9b30SMilanka Ringwald 		break;
472a4cd9b30SMilanka Ringwald 
473a4cd9b30SMilanka Ringwald 		case EFFECT_SET_VOLUME:
474a4cd9b30SMilanka Ringwald 			/*
475a4cd9b30SMilanka Ringwald 			[12]: Set volume
476a4cd9b30SMilanka Ringwald 			Where [12][x][y] means "set current sample's volume to x*16+y".
477a4cd9b30SMilanka Ringwald 			Legal volumes are 0..64.
478a4cd9b30SMilanka Ringwald 			*/
479a4cd9b30SMilanka Ringwald 
480a4cd9b30SMilanka Ringwald 			cptr->volume = (effect & 0xFF);
481a4cd9b30SMilanka Ringwald 		break;
482a4cd9b30SMilanka Ringwald 
483a4cd9b30SMilanka Ringwald 		case EFFECT_PATTERN_BREAK:
484a4cd9b30SMilanka Ringwald 			/*
485a4cd9b30SMilanka Ringwald 			[13]: Pattern Break
486a4cd9b30SMilanka Ringwald 			Where [13][x][y] means "stop the pattern after this division, and
487a4cd9b30SMilanka Ringwald 			continue the song at the next pattern at division x*10+y" (the 10
488a4cd9b30SMilanka Ringwald 			is not a typo). Legal divisions are from 0 to 63 (note Protracker
489a4cd9b30SMilanka Ringwald 			exception above).
490a4cd9b30SMilanka Ringwald 			*/
491a4cd9b30SMilanka Ringwald 
492a4cd9b30SMilanka Ringwald 			mod->patternpos = ( ((effect>>4)&0xF)*10 + (effect&0xF) ) * mod->number_of_channels;
493a4cd9b30SMilanka Ringwald 			mod->jump_loop_effect = 1;
494a4cd9b30SMilanka Ringwald 			mod->tablepos++;
495a4cd9b30SMilanka Ringwald 			if(mod->tablepos >= mod->song.length)
496a4cd9b30SMilanka Ringwald 				mod->tablepos = 0;
497a4cd9b30SMilanka Ringwald 
498a4cd9b30SMilanka Ringwald 		break;
499a4cd9b30SMilanka Ringwald 
500a4cd9b30SMilanka Ringwald 		case EFFECT_EXTENDED:
501a4cd9b30SMilanka Ringwald 			switch( (effect>>4) & 0xF )
502a4cd9b30SMilanka Ringwald 			{
503a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_PORTA_UP:
504a4cd9b30SMilanka Ringwald 					/*
505a4cd9b30SMilanka Ringwald 					[14][1]: Fineslide up
506a4cd9b30SMilanka Ringwald 					Where [14][1][x] means "decrement the period of the current sample
507a4cd9b30SMilanka Ringwald 					by x". The incrementing takes place at the beginning of the
508a4cd9b30SMilanka Ringwald 					division, and hence there is no actual sliding. You cannot slide
509a4cd9b30SMilanka Ringwald 					beyond the note B3 (period 113).
510a4cd9b30SMilanka Ringwald 					*/
511a4cd9b30SMilanka Ringwald 
512a4cd9b30SMilanka Ringwald 					cptr->period -= (effect & 0xF);
513a4cd9b30SMilanka Ringwald 					if( cptr->period < 113 )
514a4cd9b30SMilanka Ringwald 						cptr->period = 113;
515a4cd9b30SMilanka Ringwald 				break;
516a4cd9b30SMilanka Ringwald 
517a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_PORTA_DOWN:
518a4cd9b30SMilanka Ringwald 					/*
519a4cd9b30SMilanka Ringwald 					[14][2]: Fineslide down
520a4cd9b30SMilanka Ringwald 					Where [14][2][x] means "increment the period of the current sample
521a4cd9b30SMilanka Ringwald 					by x". Similar to [14][1] but shifts the pitch down. You cannot
522a4cd9b30SMilanka Ringwald 					slide beyond the note C1 (period 856).
523a4cd9b30SMilanka Ringwald 					*/
524a4cd9b30SMilanka Ringwald 
525a4cd9b30SMilanka Ringwald 					cptr->period += (effect & 0xF);
526a4cd9b30SMilanka Ringwald 					if( cptr->period > 856 )
527a4cd9b30SMilanka Ringwald 						cptr->period = 856;
528a4cd9b30SMilanka Ringwald 				break;
529a4cd9b30SMilanka Ringwald 
530a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_VOLSLIDE_UP:
531a4cd9b30SMilanka Ringwald 					/*
532a4cd9b30SMilanka Ringwald 					[14][10]: Fine volume slide up
533a4cd9b30SMilanka Ringwald 					Where [14][10][x] means "increment the volume of the current sample
534a4cd9b30SMilanka Ringwald 					by x". The incrementing takes place at the beginning of the
535a4cd9b30SMilanka Ringwald 					division, and hence there is no sliding. You cannot slide beyond
536a4cd9b30SMilanka Ringwald 					volume 64.
537a4cd9b30SMilanka Ringwald 					*/
538a4cd9b30SMilanka Ringwald 
539a4cd9b30SMilanka Ringwald 					cptr->volume += (effect & 0xF);
540a4cd9b30SMilanka Ringwald 					if( cptr->volume>64 )
541a4cd9b30SMilanka Ringwald 						cptr->volume = 64;
542a4cd9b30SMilanka Ringwald 				break;
543a4cd9b30SMilanka Ringwald 
544a4cd9b30SMilanka Ringwald 				case EFFECT_E_FINE_VOLSLIDE_DOWN:
545a4cd9b30SMilanka Ringwald 					/*
546a4cd9b30SMilanka Ringwald 					[14][11]: Fine volume slide down
547a4cd9b30SMilanka Ringwald 					Where [14][11][x] means "decrement the volume of the current sample
548a4cd9b30SMilanka Ringwald 					by x". Similar to [14][10] but lowers volume. You cannot slide
549a4cd9b30SMilanka Ringwald 					beyond volume 0.
550a4cd9b30SMilanka Ringwald 					*/
551a4cd9b30SMilanka Ringwald 
552a4cd9b30SMilanka Ringwald 					cptr->volume -= (effect & 0xF);
553a4cd9b30SMilanka Ringwald 					if( cptr->volume > 200 )
554a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
555a4cd9b30SMilanka Ringwald 				break;
556a4cd9b30SMilanka Ringwald 
557a4cd9b30SMilanka Ringwald 				case EFFECT_E_PATTERN_LOOP:
558a4cd9b30SMilanka Ringwald 					/*
559a4cd9b30SMilanka Ringwald 					[14][6]: Loop pattern
560a4cd9b30SMilanka Ringwald 					Where [14][6][x] means "set the start of a loop to this division if
561a4cd9b30SMilanka Ringwald 					x is 0, otherwise after this division, jump back to the start of a
562a4cd9b30SMilanka Ringwald 					loop and play it another x times before continuing". If the start
563a4cd9b30SMilanka Ringwald 					of the loop was not set, it will default to the start of the
564a4cd9b30SMilanka Ringwald 					current pattern. Hence 'loop pattern' cannot be performed across
565a4cd9b30SMilanka Ringwald 					multiple patterns. Note that loops do not support nesting, and you
566a4cd9b30SMilanka Ringwald 					may generate an infinite loop if you try to nest 'loop pattern's.
567a4cd9b30SMilanka Ringwald 					*/
568a4cd9b30SMilanka Ringwald 
569a4cd9b30SMilanka Ringwald 					if( effect & 0xF )
570a4cd9b30SMilanka Ringwald 					{
571a4cd9b30SMilanka Ringwald 						if( cptr->patternloopcnt )
572a4cd9b30SMilanka Ringwald 						{
573a4cd9b30SMilanka Ringwald 							cptr->patternloopcnt--;
574a4cd9b30SMilanka Ringwald 							if( cptr->patternloopcnt )
575a4cd9b30SMilanka Ringwald 							{
576a4cd9b30SMilanka Ringwald 								mod->patternpos = cptr->patternloopstartpoint;
577a4cd9b30SMilanka Ringwald 								mod->jump_loop_effect = 1;
578a4cd9b30SMilanka Ringwald 							}
579a4cd9b30SMilanka Ringwald 							else
580a4cd9b30SMilanka Ringwald 							{
581a4cd9b30SMilanka Ringwald 								cptr->patternloopstartpoint = mod->patternpos ;
582a4cd9b30SMilanka Ringwald 							}
583a4cd9b30SMilanka Ringwald 						}
584a4cd9b30SMilanka Ringwald 						else
585a4cd9b30SMilanka Ringwald 						{
586a4cd9b30SMilanka Ringwald 							cptr->patternloopcnt = (effect & 0xF);
587a4cd9b30SMilanka Ringwald 							mod->patternpos = cptr->patternloopstartpoint;
588a4cd9b30SMilanka Ringwald 							mod->jump_loop_effect = 1;
589a4cd9b30SMilanka Ringwald 						}
590a4cd9b30SMilanka Ringwald 					}
591a4cd9b30SMilanka Ringwald 					else // Start point
592a4cd9b30SMilanka Ringwald 					{
593a4cd9b30SMilanka Ringwald 						cptr->patternloopstartpoint = mod->patternpos;
594a4cd9b30SMilanka Ringwald 					}
595a4cd9b30SMilanka Ringwald 
596a4cd9b30SMilanka Ringwald 				break;
597a4cd9b30SMilanka Ringwald 
598a4cd9b30SMilanka Ringwald 				case EFFECT_E_PATTERN_DELAY:
599a4cd9b30SMilanka Ringwald 					/*
600a4cd9b30SMilanka Ringwald 					[14][14]: Delay pattern
601a4cd9b30SMilanka Ringwald 					Where [14][14][x] means "after this division there will be a delay
602a4cd9b30SMilanka Ringwald 					equivalent to the time taken to play x divisions after which the
603a4cd9b30SMilanka Ringwald 					pattern will be resumed". The delay only relates to the
604a4cd9b30SMilanka Ringwald 					interpreting of new divisions, and all effects and previous notes
605a4cd9b30SMilanka Ringwald 					continue during delay.
606a4cd9b30SMilanka Ringwald 					*/
607a4cd9b30SMilanka Ringwald 
608a4cd9b30SMilanka Ringwald 					mod->patterndelay = (effect & 0xF);
609a4cd9b30SMilanka Ringwald 				break;
610a4cd9b30SMilanka Ringwald 
611a4cd9b30SMilanka Ringwald 				case EFFECT_E_NOTE_CUT:
612a4cd9b30SMilanka Ringwald 					/*
613a4cd9b30SMilanka Ringwald 					[14][12]: Cut sample
614a4cd9b30SMilanka Ringwald 					Where [14][12][x] means "after the current sample has been played
615a4cd9b30SMilanka Ringwald 					for x ticks in this division, its volume will be set to 0". This
616a4cd9b30SMilanka Ringwald 					implies that if x is 0, then you will not hear any of the sample.
617a4cd9b30SMilanka Ringwald 					If you wish to insert "silence" in a pattern, it is better to use a
618a4cd9b30SMilanka Ringwald 					"silence"-sample (see above) due to the lack of proper support for
619a4cd9b30SMilanka Ringwald 					this effect.
620a4cd9b30SMilanka Ringwald 					*/
621a4cd9b30SMilanka Ringwald 					cptr->effect = EFFECT_E_NOTE_CUT;
622a4cd9b30SMilanka Ringwald 					cptr->cut_param = (effect & 0xF);
623a4cd9b30SMilanka Ringwald 					if(!cptr->cut_param)
624a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
625a4cd9b30SMilanka Ringwald 				break;
626a4cd9b30SMilanka Ringwald 
627a4cd9b30SMilanka Ringwald 				default:
628a4cd9b30SMilanka Ringwald 
629a4cd9b30SMilanka Ringwald 				break;
630a4cd9b30SMilanka Ringwald 			}
631a4cd9b30SMilanka Ringwald 		break;
632a4cd9b30SMilanka Ringwald 
633a4cd9b30SMilanka Ringwald 		case 0xF:
634a4cd9b30SMilanka Ringwald 			/*
635a4cd9b30SMilanka Ringwald 			[15]: Set speed
636a4cd9b30SMilanka Ringwald 			Where [15][x][y] means "set speed to x*16+y". Though it is nowhere
637a4cd9b30SMilanka Ringwald 			near that simple. Let z = x*16+y. Depending on what values z takes,
638a4cd9b30SMilanka Ringwald 			different units of speed are set, there being two: ticks/division
639a4cd9b30SMilanka Ringwald 			and beats/minute (though this one is only a label and not strictly
640a4cd9b30SMilanka Ringwald 			true). If z=0, then what should technically happen is that the
641a4cd9b30SMilanka Ringwald 			module stops, but in practice it is treated as if z=1, because
642a4cd9b30SMilanka Ringwald 			there is already a method for stopping the module (running out of
643a4cd9b30SMilanka Ringwald 			patterns). If z<=32, then it means "set ticks/division to z"
644a4cd9b30SMilanka Ringwald 			otherwise it means "set beats/minute to z" (convention says that
645a4cd9b30SMilanka Ringwald 			this should read "If z<32.." but there are some composers out there
646a4cd9b30SMilanka Ringwald 			that defy conventions). Default values are 6 ticks/division, and
647a4cd9b30SMilanka Ringwald 			125 beats/minute (4 divisions = 1 beat). The beats/minute tag is
648a4cd9b30SMilanka Ringwald 			only meaningful for 6 ticks/division. To get a more accurate view
649a4cd9b30SMilanka Ringwald 			of how things work, use the following formula:
650a4cd9b30SMilanka Ringwald 									 24 * beats/minute
651a4cd9b30SMilanka Ringwald 				  divisions/minute = -----------------
652a4cd9b30SMilanka Ringwald 									  ticks/division
653a4cd9b30SMilanka Ringwald 			Hence divisions/minute range from 24.75 to 6120, eg. to get a value
654a4cd9b30SMilanka Ringwald 			of 2000 divisions/minute use 3 ticks/division and 250 beats/minute.
655a4cd9b30SMilanka Ringwald 			If multiple "set speed" effects are performed in a single division,
656a4cd9b30SMilanka Ringwald 			the ones on higher-numbered channels take precedence over the ones
657a4cd9b30SMilanka Ringwald 			on lower-numbered channels. This effect has a large number of
658a4cd9b30SMilanka Ringwald 			different implementations, but the one described here has the
659a4cd9b30SMilanka Ringwald 			widest usage.
660a4cd9b30SMilanka Ringwald 			*/
661a4cd9b30SMilanka Ringwald 
662a4cd9b30SMilanka Ringwald 			if( (effect&0xFF) < 0x21 )
663a4cd9b30SMilanka Ringwald 			{
664a4cd9b30SMilanka Ringwald 				if( effect&0xFF )
665a4cd9b30SMilanka Ringwald 				{
666a4cd9b30SMilanka Ringwald 					mod->song.speed = effect&0xFF;
667a4cd9b30SMilanka Ringwald 					mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
668a4cd9b30SMilanka Ringwald 				}
669a4cd9b30SMilanka Ringwald 			}
670a4cd9b30SMilanka Ringwald 
671a4cd9b30SMilanka Ringwald 			if( (effect&0xFF) >= 0x21 )
672a4cd9b30SMilanka Ringwald 			{
673a4cd9b30SMilanka Ringwald 				///	 HZ = 2 * BPM / 5
674a4cd9b30SMilanka Ringwald 				mod->bpm = effect&0xFF;
675a4cd9b30SMilanka Ringwald 				mod->patternticksaim = (long)mod->song.speed * ((mod->playrate * 5 ) / (((long)2 * (long)mod->bpm)));
676a4cd9b30SMilanka Ringwald 			}
677a4cd9b30SMilanka Ringwald 
678a4cd9b30SMilanka Ringwald 		break;
679a4cd9b30SMilanka Ringwald 
680a4cd9b30SMilanka Ringwald 		default:
681a4cd9b30SMilanka Ringwald 		// Unsupported effect
682a4cd9b30SMilanka Ringwald 		break;
683a4cd9b30SMilanka Ringwald 
684a4cd9b30SMilanka Ringwald 	}
685a4cd9b30SMilanka Ringwald 
686a4cd9b30SMilanka Ringwald }
687a4cd9b30SMilanka Ringwald 
688a4cd9b30SMilanka Ringwald static void workeffect( note * nptr, channel * cptr )
689a4cd9b30SMilanka Ringwald {
690*c5456c21SMilanka Ringwald 	(void) nptr;
691*c5456c21SMilanka Ringwald 
692a4cd9b30SMilanka Ringwald 	switch(cptr->effect)
693a4cd9b30SMilanka Ringwald 	{
694a4cd9b30SMilanka Ringwald 		case EFFECT_ARPEGGIO:
695a4cd9b30SMilanka Ringwald 
696a4cd9b30SMilanka Ringwald 			if( cptr->parameffect )
697a4cd9b30SMilanka Ringwald 			{
698a4cd9b30SMilanka Ringwald 				cptr->decalperiod = cptr->period - cptr->Arpperiods[cptr->ArpIndex];
699a4cd9b30SMilanka Ringwald 
700a4cd9b30SMilanka Ringwald 				cptr->ArpIndex++;
701a4cd9b30SMilanka Ringwald 				if( cptr->ArpIndex>2 )
702a4cd9b30SMilanka Ringwald 					cptr->ArpIndex = 0;
703a4cd9b30SMilanka Ringwald 			}
704a4cd9b30SMilanka Ringwald 		break;
705a4cd9b30SMilanka Ringwald 
706a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_UP:
707a4cd9b30SMilanka Ringwald 
708a4cd9b30SMilanka Ringwald 			if(cptr->period)
709a4cd9b30SMilanka Ringwald 			{
710a4cd9b30SMilanka Ringwald 				cptr->period -= cptr->parameffect;
711a4cd9b30SMilanka Ringwald 
712a4cd9b30SMilanka Ringwald 				if( cptr->period < 113 || cptr->period > 20000 )
713a4cd9b30SMilanka Ringwald 					cptr->period = 113;
714a4cd9b30SMilanka Ringwald 			}
715a4cd9b30SMilanka Ringwald 
716a4cd9b30SMilanka Ringwald 		break;
717a4cd9b30SMilanka Ringwald 
718a4cd9b30SMilanka Ringwald 		case EFFECT_PORTAMENTO_DOWN:
719a4cd9b30SMilanka Ringwald 
720a4cd9b30SMilanka Ringwald 			if(cptr->period)
721a4cd9b30SMilanka Ringwald 			{
722a4cd9b30SMilanka Ringwald 				cptr->period += cptr->parameffect;
723a4cd9b30SMilanka Ringwald 
724a4cd9b30SMilanka Ringwald 				if( cptr->period > 20000 )
725a4cd9b30SMilanka Ringwald 					cptr->period = 20000;
726a4cd9b30SMilanka Ringwald 			}
727a4cd9b30SMilanka Ringwald 
728a4cd9b30SMilanka Ringwald 		break;
729a4cd9b30SMilanka Ringwald 
730a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_TONEPORTA:
731a4cd9b30SMilanka Ringwald 		case EFFECT_TONE_PORTAMENTO:
732a4cd9b30SMilanka Ringwald 
733a4cd9b30SMilanka Ringwald 			if( cptr->period && ( cptr->period != cptr->portaperiod ) && cptr->portaperiod )
734a4cd9b30SMilanka Ringwald 			{
735a4cd9b30SMilanka Ringwald 				if( cptr->period > cptr->portaperiod )
736a4cd9b30SMilanka Ringwald 				{
737a4cd9b30SMilanka Ringwald 					if( cptr->period - cptr->portaperiod >= cptr->portaspeed )
738a4cd9b30SMilanka Ringwald 					{
739a4cd9b30SMilanka Ringwald 						cptr->period -= cptr->portaspeed;
740a4cd9b30SMilanka Ringwald 					}
741a4cd9b30SMilanka Ringwald 					else
742a4cd9b30SMilanka Ringwald 					{
743a4cd9b30SMilanka Ringwald 						cptr->period = cptr->portaperiod;
744a4cd9b30SMilanka Ringwald 					}
745a4cd9b30SMilanka Ringwald 				}
746a4cd9b30SMilanka Ringwald 				else
747a4cd9b30SMilanka Ringwald 				{
748a4cd9b30SMilanka Ringwald 					if( cptr->portaperiod - cptr->period >= cptr->portaspeed )
749a4cd9b30SMilanka Ringwald 					{
750a4cd9b30SMilanka Ringwald 						cptr->period += cptr->portaspeed;
751a4cd9b30SMilanka Ringwald 					}
752a4cd9b30SMilanka Ringwald 					else
753a4cd9b30SMilanka Ringwald 					{
754a4cd9b30SMilanka Ringwald 						cptr->period = cptr->portaperiod;
755a4cd9b30SMilanka Ringwald 					}
756a4cd9b30SMilanka Ringwald 				}
757a4cd9b30SMilanka Ringwald 
758a4cd9b30SMilanka Ringwald 				if( cptr->period == cptr->portaperiod )
759a4cd9b30SMilanka Ringwald 				{
760a4cd9b30SMilanka Ringwald 					// If the slide is over, don't let it to be retriggered.
761a4cd9b30SMilanka Ringwald 					cptr->portaperiod = 0;
762a4cd9b30SMilanka Ringwald 				}
763a4cd9b30SMilanka Ringwald 			}
764a4cd9b30SMilanka Ringwald 
765a4cd9b30SMilanka Ringwald 			if( cptr->effect == EFFECT_VOLSLIDE_TONEPORTA )
766a4cd9b30SMilanka Ringwald 			{
767a4cd9b30SMilanka Ringwald 				if( cptr->volumeslide > 0x0F )
768a4cd9b30SMilanka Ringwald 				{
769a4cd9b30SMilanka Ringwald 					cptr->volume = cptr->volume + (cptr->volumeslide>>4);
770a4cd9b30SMilanka Ringwald 
771a4cd9b30SMilanka Ringwald 					if(cptr->volume>63)
772a4cd9b30SMilanka Ringwald 						cptr->volume = 63;
773a4cd9b30SMilanka Ringwald 				}
774a4cd9b30SMilanka Ringwald 				else
775a4cd9b30SMilanka Ringwald 				{
776a4cd9b30SMilanka Ringwald 					cptr->volume = cptr->volume - (cptr->volumeslide);
777a4cd9b30SMilanka Ringwald 
778a4cd9b30SMilanka Ringwald 					if(cptr->volume>63)
779a4cd9b30SMilanka Ringwald 						cptr->volume=0;
780a4cd9b30SMilanka Ringwald 				}
781a4cd9b30SMilanka Ringwald 			}
782a4cd9b30SMilanka Ringwald 		break;
783a4cd9b30SMilanka Ringwald 
784a4cd9b30SMilanka Ringwald 		case EFFECT_VOLSLIDE_VIBRATO:
785a4cd9b30SMilanka Ringwald 		case EFFECT_VIBRATO:
786a4cd9b30SMilanka Ringwald 
787a4cd9b30SMilanka Ringwald 			cptr->vibraperiod = ( (cptr->vibraparam&0xF) * sintable[cptr->vibrapointeur&0x1F] )>>7;
788a4cd9b30SMilanka Ringwald 
789a4cd9b30SMilanka Ringwald 			if( cptr->vibrapointeur > 31 )
790a4cd9b30SMilanka Ringwald 				cptr->vibraperiod = -cptr->vibraperiod;
791a4cd9b30SMilanka Ringwald 
792a4cd9b30SMilanka Ringwald 			cptr->vibrapointeur = (cptr->vibrapointeur+(((cptr->vibraparam>>4))&0xf)) & 0x3F;
793a4cd9b30SMilanka Ringwald 
794a4cd9b30SMilanka Ringwald 			if( cptr->effect == EFFECT_VOLSLIDE_VIBRATO )
795a4cd9b30SMilanka Ringwald 			{
796a4cd9b30SMilanka Ringwald 				if( cptr->volumeslide > 0xF )
797a4cd9b30SMilanka Ringwald 				{
798a4cd9b30SMilanka Ringwald 					cptr->volume = cptr->volume+(cptr->volumeslide>>4);
799a4cd9b30SMilanka Ringwald 
800a4cd9b30SMilanka Ringwald 					if( cptr->volume > 64 )
801a4cd9b30SMilanka Ringwald 						cptr->volume = 64;
802a4cd9b30SMilanka Ringwald 				}
803a4cd9b30SMilanka Ringwald 				else
804a4cd9b30SMilanka Ringwald 				{
805a4cd9b30SMilanka Ringwald 					cptr->volume = cptr->volume - cptr->volumeslide;
806a4cd9b30SMilanka Ringwald 
807a4cd9b30SMilanka Ringwald 					if( cptr->volume > 64 )
808a4cd9b30SMilanka Ringwald 						cptr->volume = 0;
809a4cd9b30SMilanka Ringwald 				}
810a4cd9b30SMilanka Ringwald 			}
811a4cd9b30SMilanka Ringwald 
812a4cd9b30SMilanka Ringwald 		break;
813a4cd9b30SMilanka Ringwald 
814a4cd9b30SMilanka Ringwald 		case EFFECT_VOLUME_SLIDE:
815a4cd9b30SMilanka Ringwald 
816a4cd9b30SMilanka Ringwald 			if( cptr->volumeslide > 0xF )
817a4cd9b30SMilanka Ringwald 			{
818a4cd9b30SMilanka Ringwald 				cptr->volume += (cptr->volumeslide>>4);
819a4cd9b30SMilanka Ringwald 
820a4cd9b30SMilanka Ringwald 				if( cptr->volume > 64 )
821a4cd9b30SMilanka Ringwald 					cptr->volume = 64;
822a4cd9b30SMilanka Ringwald 			}
823a4cd9b30SMilanka Ringwald 			else
824a4cd9b30SMilanka Ringwald 			{
825a4cd9b30SMilanka Ringwald 				cptr->volume -= (cptr->volumeslide&0xf);
826a4cd9b30SMilanka Ringwald 
827a4cd9b30SMilanka Ringwald 				if( cptr->volume > 64 )
828a4cd9b30SMilanka Ringwald 					cptr->volume = 0;
829a4cd9b30SMilanka Ringwald 			}
830a4cd9b30SMilanka Ringwald 		break;
831a4cd9b30SMilanka Ringwald 
832a4cd9b30SMilanka Ringwald 		case EFFECT_E_NOTE_CUT:
833a4cd9b30SMilanka Ringwald 			if(cptr->cut_param)
834a4cd9b30SMilanka Ringwald 				cptr->cut_param--;
835a4cd9b30SMilanka Ringwald 
836a4cd9b30SMilanka Ringwald 			if(!cptr->cut_param)
837a4cd9b30SMilanka Ringwald 				cptr->volume = 0;
838a4cd9b30SMilanka Ringwald 		break;
839a4cd9b30SMilanka Ringwald 
840a4cd9b30SMilanka Ringwald 		default:
841a4cd9b30SMilanka Ringwald 		break;
842a4cd9b30SMilanka Ringwald 
843a4cd9b30SMilanka Ringwald 	}
844a4cd9b30SMilanka Ringwald 
845a4cd9b30SMilanka Ringwald }
846a4cd9b30SMilanka Ringwald 
847a4cd9b30SMilanka Ringwald ///////////////////////////////////////////////////////////////////////////////////
848a4cd9b30SMilanka Ringwald int hxcmod_init(modcontext * modctx)
849a4cd9b30SMilanka Ringwald {
850a4cd9b30SMilanka Ringwald 	muint i,j;
851a4cd9b30SMilanka Ringwald 
852a4cd9b30SMilanka Ringwald 	if( modctx )
853a4cd9b30SMilanka Ringwald 	{
854a4cd9b30SMilanka Ringwald 		memclear(modctx,0,sizeof(modcontext));
855a4cd9b30SMilanka Ringwald 		modctx->playrate = 44100;
856a4cd9b30SMilanka Ringwald 		modctx->stereo = 1;
857a4cd9b30SMilanka Ringwald 		modctx->stereo_separation = 1;
858a4cd9b30SMilanka Ringwald 		modctx->bits = 16;
859a4cd9b30SMilanka Ringwald 		modctx->filter = 1;
860a4cd9b30SMilanka Ringwald 
861a4cd9b30SMilanka Ringwald 		for(i=0;i<PERIOD_TABLE_LENGTH - 1;i++)
862a4cd9b30SMilanka Ringwald 		{
863a4cd9b30SMilanka Ringwald 			for(j=0;j<8;j++)
864a4cd9b30SMilanka Ringwald 			{
865a4cd9b30SMilanka Ringwald 				modctx->fullperiod[(i*8) + j] = periodtable[i] - ((( periodtable[i] - periodtable[i+1] ) / 8) * j);
866a4cd9b30SMilanka Ringwald 			}
867a4cd9b30SMilanka Ringwald 		}
868a4cd9b30SMilanka Ringwald 
869a4cd9b30SMilanka Ringwald 		return 1;
870a4cd9b30SMilanka Ringwald 	}
871a4cd9b30SMilanka Ringwald 
872a4cd9b30SMilanka Ringwald 	return 0;
873a4cd9b30SMilanka Ringwald }
874a4cd9b30SMilanka Ringwald 
875a4cd9b30SMilanka Ringwald int hxcmod_setcfg(modcontext * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter)
876a4cd9b30SMilanka Ringwald {
877a4cd9b30SMilanka Ringwald 	if( modctx )
878a4cd9b30SMilanka Ringwald 	{
879a4cd9b30SMilanka Ringwald 		modctx->playrate = samplerate;
880a4cd9b30SMilanka Ringwald 
881a4cd9b30SMilanka Ringwald 		if( stereo )
882a4cd9b30SMilanka Ringwald 			modctx->stereo = 1;
883a4cd9b30SMilanka Ringwald 		else
884a4cd9b30SMilanka Ringwald 			modctx->stereo = 0;
885a4cd9b30SMilanka Ringwald 
886a4cd9b30SMilanka Ringwald 		if(stereo_separation < 4)
887a4cd9b30SMilanka Ringwald 		{
888a4cd9b30SMilanka Ringwald 			modctx->stereo_separation = stereo_separation;
889a4cd9b30SMilanka Ringwald 		}
890a4cd9b30SMilanka Ringwald 
891a4cd9b30SMilanka Ringwald 		if( bits == 8 || bits == 16 )
892a4cd9b30SMilanka Ringwald 		{
893a4cd9b30SMilanka Ringwald 			modctx->bits = bits;
894a4cd9b30SMilanka Ringwald 		}
895a4cd9b30SMilanka Ringwald 
896a4cd9b30SMilanka Ringwald 		if( filter )
897a4cd9b30SMilanka Ringwald 			modctx->filter = 1;
898a4cd9b30SMilanka Ringwald 		else
899a4cd9b30SMilanka Ringwald 			modctx->filter = 0;
900a4cd9b30SMilanka Ringwald 
901a4cd9b30SMilanka Ringwald 		return 1;
902a4cd9b30SMilanka Ringwald 	}
903a4cd9b30SMilanka Ringwald 
904a4cd9b30SMilanka Ringwald 	return 0;
905a4cd9b30SMilanka Ringwald }
906a4cd9b30SMilanka Ringwald 
907a4cd9b30SMilanka Ringwald int hxcmod_load( modcontext * modctx, void * mod_data, int mod_data_size )
908a4cd9b30SMilanka Ringwald {
909a4cd9b30SMilanka Ringwald 	muint i, max;
910a4cd9b30SMilanka Ringwald 	unsigned short t;
911a4cd9b30SMilanka Ringwald 	sample *sptr;
912a4cd9b30SMilanka Ringwald 	unsigned char * modmemory,* endmodmemory;
913a4cd9b30SMilanka Ringwald 
914a4cd9b30SMilanka Ringwald 	modmemory = (unsigned char *)mod_data;
915a4cd9b30SMilanka Ringwald 	endmodmemory = modmemory + mod_data_size;
916a4cd9b30SMilanka Ringwald 
917a4cd9b30SMilanka Ringwald 	if(modmemory)
918a4cd9b30SMilanka Ringwald 	{
919a4cd9b30SMilanka Ringwald 		if( modctx )
920a4cd9b30SMilanka Ringwald 		{
921a4cd9b30SMilanka Ringwald 			memcopy(&(modctx->song.title),modmemory,1084);
922a4cd9b30SMilanka Ringwald 
923a4cd9b30SMilanka Ringwald 			i = 0;
924a4cd9b30SMilanka Ringwald 			modctx->number_of_channels = 0;
925a4cd9b30SMilanka Ringwald 			while(modlist[i].numberofchannels)
926a4cd9b30SMilanka Ringwald 			{
927a4cd9b30SMilanka Ringwald 				if(memcompare(modctx->song.signature,modlist[i].signature,4))
928a4cd9b30SMilanka Ringwald 				{
929a4cd9b30SMilanka Ringwald 					modctx->number_of_channels = modlist[i].numberofchannels;
930a4cd9b30SMilanka Ringwald 				}
931a4cd9b30SMilanka Ringwald 
932a4cd9b30SMilanka Ringwald 				i++;
933a4cd9b30SMilanka Ringwald 			}
934a4cd9b30SMilanka Ringwald 
935a4cd9b30SMilanka Ringwald 			if( !modctx->number_of_channels )
936a4cd9b30SMilanka Ringwald 			{
937a4cd9b30SMilanka Ringwald 				// 15 Samples modules support
938a4cd9b30SMilanka Ringwald 				// Shift the whole datas to make it look likes a standard 4 channels mod.
939a4cd9b30SMilanka Ringwald 				memcopy(&(modctx->song.signature), "M.K.", 4);
940a4cd9b30SMilanka Ringwald 				memcopy(&(modctx->song.length), &(modctx->song.samples[15]), 130);
941a4cd9b30SMilanka Ringwald 				memclear(&(modctx->song.samples[15]), 0, 480);
942a4cd9b30SMilanka Ringwald 				modmemory += 600;
943a4cd9b30SMilanka Ringwald 				modctx->number_of_channels = 4;
944a4cd9b30SMilanka Ringwald 			}
945a4cd9b30SMilanka Ringwald 			else
946a4cd9b30SMilanka Ringwald 			{
947a4cd9b30SMilanka Ringwald 				modmemory += 1084;
948a4cd9b30SMilanka Ringwald 			}
949a4cd9b30SMilanka Ringwald 
950a4cd9b30SMilanka Ringwald 			if( modmemory >= endmodmemory )
951a4cd9b30SMilanka Ringwald 				return 0; // End passed ? - Probably a bad file !
952a4cd9b30SMilanka Ringwald 
953a4cd9b30SMilanka Ringwald 			// Patterns loading
954a4cd9b30SMilanka Ringwald 			for (i = max = 0; i < 128; i++)
955a4cd9b30SMilanka Ringwald 			{
956a4cd9b30SMilanka Ringwald 				while (max <= modctx->song.patterntable[i])
957a4cd9b30SMilanka Ringwald 				{
958a4cd9b30SMilanka Ringwald 					modctx->patterndata[max] = (note*)modmemory;
959a4cd9b30SMilanka Ringwald 					modmemory += (256*modctx->number_of_channels);
960a4cd9b30SMilanka Ringwald 					max++;
961a4cd9b30SMilanka Ringwald 
962a4cd9b30SMilanka Ringwald 					if( modmemory >= endmodmemory )
963a4cd9b30SMilanka Ringwald 						return 0; // End passed ? - Probably a bad file !
964a4cd9b30SMilanka Ringwald 				}
965a4cd9b30SMilanka Ringwald 			}
966a4cd9b30SMilanka Ringwald 
967a4cd9b30SMilanka Ringwald 			for (i = 0; i < 31; i++)
968a4cd9b30SMilanka Ringwald 				modctx->sampledata[i]=0;
969a4cd9b30SMilanka Ringwald 
970a4cd9b30SMilanka Ringwald 			// Samples loading
971a4cd9b30SMilanka Ringwald 			for (i = 0, sptr = modctx->song.samples; i <31; i++, sptr++)
972a4cd9b30SMilanka Ringwald 			{
973a4cd9b30SMilanka Ringwald 				t= (sptr->length &0xFF00)>>8 | (sptr->length &0xFF)<<8;
974a4cd9b30SMilanka Ringwald 				sptr->length = t*2;
975a4cd9b30SMilanka Ringwald 
976a4cd9b30SMilanka Ringwald 				t= (sptr->reppnt &0xFF00)>>8 | (sptr->reppnt &0xFF)<<8;
977a4cd9b30SMilanka Ringwald 				sptr->reppnt = t*2;
978a4cd9b30SMilanka Ringwald 
979a4cd9b30SMilanka Ringwald 				t= (sptr->replen &0xFF00)>>8 | (sptr->replen &0xFF)<<8;
980a4cd9b30SMilanka Ringwald 				sptr->replen = t*2;
981a4cd9b30SMilanka Ringwald 
982a4cd9b30SMilanka Ringwald 
983a4cd9b30SMilanka Ringwald 				if (sptr->length == 0) continue;
984a4cd9b30SMilanka Ringwald 
985a4cd9b30SMilanka Ringwald 				modctx->sampledata[i] = (char*)modmemory;
986a4cd9b30SMilanka Ringwald 				modmemory += sptr->length;
987a4cd9b30SMilanka Ringwald 
988a4cd9b30SMilanka Ringwald 				if (sptr->replen + sptr->reppnt > sptr->length)
989a4cd9b30SMilanka Ringwald 					sptr->replen = sptr->length - sptr->reppnt;
990a4cd9b30SMilanka Ringwald 
991a4cd9b30SMilanka Ringwald 				if( modmemory > endmodmemory )
992a4cd9b30SMilanka Ringwald 					return 0; // End passed ? - Probably a bad file !
993a4cd9b30SMilanka Ringwald 			}
994a4cd9b30SMilanka Ringwald 
995a4cd9b30SMilanka Ringwald 			// States init
996a4cd9b30SMilanka Ringwald 
997a4cd9b30SMilanka Ringwald 			modctx->tablepos = 0;
998a4cd9b30SMilanka Ringwald 			modctx->patternpos = 0;
999a4cd9b30SMilanka Ringwald 			modctx->song.speed = 6;
1000a4cd9b30SMilanka Ringwald 			modctx->bpm = 125;
1001a4cd9b30SMilanka Ringwald 			modctx->samplenb = 0;
1002a4cd9b30SMilanka Ringwald 
1003a4cd9b30SMilanka Ringwald 			modctx->patternticks = (((long)modctx->song.speed * modctx->playrate * 5)/ (2 * modctx->bpm)) + 1;
1004a4cd9b30SMilanka Ringwald 			modctx->patternticksaim = ((long)modctx->song.speed * modctx->playrate * 5) / (2 * modctx->bpm);
1005a4cd9b30SMilanka Ringwald 
1006a4cd9b30SMilanka Ringwald 			modctx->sampleticksconst = 3546894UL / modctx->playrate; //8448*428/playrate;
1007a4cd9b30SMilanka Ringwald 
1008a4cd9b30SMilanka Ringwald 			for(i=0; i < modctx->number_of_channels; i++)
1009a4cd9b30SMilanka Ringwald 			{
1010a4cd9b30SMilanka Ringwald 				modctx->channels[i].volume = 0;
1011a4cd9b30SMilanka Ringwald 				modctx->channels[i].period = 0;
1012a4cd9b30SMilanka Ringwald 			}
1013a4cd9b30SMilanka Ringwald 
1014a4cd9b30SMilanka Ringwald 			modctx->mod_loaded = 1;
1015a4cd9b30SMilanka Ringwald 
1016a4cd9b30SMilanka Ringwald 			return 1;
1017a4cd9b30SMilanka Ringwald 		}
1018a4cd9b30SMilanka Ringwald 	}
1019a4cd9b30SMilanka Ringwald 
1020a4cd9b30SMilanka Ringwald 	return 0;
1021a4cd9b30SMilanka Ringwald }
1022a4cd9b30SMilanka Ringwald 
1023a4cd9b30SMilanka Ringwald void hxcmod_fillbuffer( modcontext * modctx, unsigned short * outbuffer, unsigned long nbsample, tracker_buffer_state * trkbuf )
1024a4cd9b30SMilanka Ringwald {
1025a4cd9b30SMilanka Ringwald 	unsigned long i, j;
1026a4cd9b30SMilanka Ringwald 	unsigned long k;
1027a4cd9b30SMilanka Ringwald 	unsigned char c;
1028a4cd9b30SMilanka Ringwald 	unsigned int state_remaining_steps;
1029a4cd9b30SMilanka Ringwald 	int l,r;
1030a4cd9b30SMilanka Ringwald 	int ll,lr;
1031a4cd9b30SMilanka Ringwald 	int tl,tr;
1032a4cd9b30SMilanka Ringwald 	short finalperiod;
1033a4cd9b30SMilanka Ringwald 	note	*nptr;
1034a4cd9b30SMilanka Ringwald 	channel *cptr;
1035a4cd9b30SMilanka Ringwald 
1036a4cd9b30SMilanka Ringwald 	if( modctx && outbuffer )
1037a4cd9b30SMilanka Ringwald 	{
1038a4cd9b30SMilanka Ringwald 		if(modctx->mod_loaded)
1039a4cd9b30SMilanka Ringwald 		{
1040a4cd9b30SMilanka Ringwald 			state_remaining_steps = 0;
1041a4cd9b30SMilanka Ringwald 
1042a4cd9b30SMilanka Ringwald 			if( trkbuf )
1043a4cd9b30SMilanka Ringwald 			{
1044a4cd9b30SMilanka Ringwald 				trkbuf->cur_rd_index = 0;
1045a4cd9b30SMilanka Ringwald 
1046a4cd9b30SMilanka Ringwald 				memcopy(trkbuf->name,modctx->song.title,sizeof(modctx->song.title));
1047a4cd9b30SMilanka Ringwald 
1048a4cd9b30SMilanka Ringwald 				for(i=0;i<31;i++)
1049a4cd9b30SMilanka Ringwald 				{
1050a4cd9b30SMilanka Ringwald 					memcopy(trkbuf->instruments[i].name,modctx->song.samples[i].name,sizeof(trkbuf->instruments[i].name));
1051a4cd9b30SMilanka Ringwald 				}
1052a4cd9b30SMilanka Ringwald 			}
1053a4cd9b30SMilanka Ringwald 
1054a4cd9b30SMilanka Ringwald 			ll = modctx->last_l_sample;
1055a4cd9b30SMilanka Ringwald 			lr = modctx->last_r_sample;
1056a4cd9b30SMilanka Ringwald 
1057a4cd9b30SMilanka Ringwald 			for (i = 0; i < nbsample; i++)
1058a4cd9b30SMilanka Ringwald 			{
1059a4cd9b30SMilanka Ringwald 				//---------------------------------------
1060a4cd9b30SMilanka Ringwald 				if( modctx->patternticks++ > modctx->patternticksaim )
1061a4cd9b30SMilanka Ringwald 				{
1062a4cd9b30SMilanka Ringwald 					if( !modctx->patterndelay )
1063a4cd9b30SMilanka Ringwald 					{
1064a4cd9b30SMilanka Ringwald 						nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1065a4cd9b30SMilanka Ringwald 						nptr = nptr + modctx->patternpos;
1066a4cd9b30SMilanka Ringwald 						cptr = modctx->channels;
1067a4cd9b30SMilanka Ringwald 
1068a4cd9b30SMilanka Ringwald 						modctx->patternticks = 0;
1069a4cd9b30SMilanka Ringwald 						modctx->patterntickse = 0;
1070a4cd9b30SMilanka Ringwald 
1071a4cd9b30SMilanka Ringwald 						for(c=0;c<modctx->number_of_channels;c++)
1072a4cd9b30SMilanka Ringwald 						{
1073a4cd9b30SMilanka Ringwald 							worknote((note*)(nptr+c), (channel*)(cptr+c),(char)(c+1),modctx);
1074a4cd9b30SMilanka Ringwald 						}
1075a4cd9b30SMilanka Ringwald 
1076a4cd9b30SMilanka Ringwald 						if( !modctx->jump_loop_effect )
1077a4cd9b30SMilanka Ringwald 							modctx->patternpos += modctx->number_of_channels;
1078a4cd9b30SMilanka Ringwald 						else
1079a4cd9b30SMilanka Ringwald 							modctx->jump_loop_effect = 0;
1080a4cd9b30SMilanka Ringwald 
1081a4cd9b30SMilanka Ringwald 						if( modctx->patternpos == 64*modctx->number_of_channels )
1082a4cd9b30SMilanka Ringwald 						{
1083a4cd9b30SMilanka Ringwald 							modctx->tablepos++;
1084a4cd9b30SMilanka Ringwald 							modctx->patternpos = 0;
1085a4cd9b30SMilanka Ringwald 							if(modctx->tablepos >= modctx->song.length)
1086a4cd9b30SMilanka Ringwald 								modctx->tablepos = 0;
1087a4cd9b30SMilanka Ringwald 						}
1088a4cd9b30SMilanka Ringwald 					}
1089a4cd9b30SMilanka Ringwald 					else
1090a4cd9b30SMilanka Ringwald 					{
1091a4cd9b30SMilanka Ringwald 						modctx->patterndelay--;
1092a4cd9b30SMilanka Ringwald 						modctx->patternticks = 0;
1093a4cd9b30SMilanka Ringwald 						modctx->patterntickse = 0;
1094a4cd9b30SMilanka Ringwald 					}
1095a4cd9b30SMilanka Ringwald 
1096a4cd9b30SMilanka Ringwald 				}
1097a4cd9b30SMilanka Ringwald 
1098a4cd9b30SMilanka Ringwald 				if( modctx->patterntickse++ > (modctx->patternticksaim/modctx->song.speed) )
1099a4cd9b30SMilanka Ringwald 				{
1100a4cd9b30SMilanka Ringwald 					nptr = modctx->patterndata[modctx->song.patterntable[modctx->tablepos]];
1101a4cd9b30SMilanka Ringwald 					nptr = nptr + modctx->patternpos;
1102a4cd9b30SMilanka Ringwald 					cptr = modctx->channels;
1103a4cd9b30SMilanka Ringwald 
1104a4cd9b30SMilanka Ringwald 					for(c=0;c<modctx->number_of_channels;c++)
1105a4cd9b30SMilanka Ringwald 					{
1106a4cd9b30SMilanka Ringwald 						workeffect(nptr+c, cptr+c);
1107a4cd9b30SMilanka Ringwald 					}
1108a4cd9b30SMilanka Ringwald 
1109a4cd9b30SMilanka Ringwald 					modctx->patterntickse = 0;
1110a4cd9b30SMilanka Ringwald 				}
1111a4cd9b30SMilanka Ringwald 
1112a4cd9b30SMilanka Ringwald 				//---------------------------------------
1113a4cd9b30SMilanka Ringwald 
1114a4cd9b30SMilanka Ringwald 				if( trkbuf && !state_remaining_steps )
1115a4cd9b30SMilanka Ringwald 				{
1116a4cd9b30SMilanka Ringwald 					if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1117a4cd9b30SMilanka Ringwald 					{
1118a4cd9b30SMilanka Ringwald 						memclear(&trkbuf->track_state_buf[trkbuf->nb_of_state],0,sizeof(tracker_state));
1119a4cd9b30SMilanka Ringwald 					}
1120a4cd9b30SMilanka Ringwald 				}
1121a4cd9b30SMilanka Ringwald 
1122a4cd9b30SMilanka Ringwald 				l=0;
1123a4cd9b30SMilanka Ringwald 				r=0;
1124a4cd9b30SMilanka Ringwald 
1125a4cd9b30SMilanka Ringwald 				for(j =0, cptr = modctx->channels; j < modctx->number_of_channels ; j++, cptr++)
1126a4cd9b30SMilanka Ringwald 				{
1127a4cd9b30SMilanka Ringwald 					if( cptr->period != 0 )
1128a4cd9b30SMilanka Ringwald 					{
1129a4cd9b30SMilanka Ringwald 						finalperiod = cptr->period - cptr->decalperiod - cptr->vibraperiod;
1130a4cd9b30SMilanka Ringwald 						if( finalperiod )
1131a4cd9b30SMilanka Ringwald 						{
1132a4cd9b30SMilanka Ringwald 							cptr->samppos += ( (modctx->sampleticksconst<<10) / finalperiod );
1133a4cd9b30SMilanka Ringwald 						}
1134a4cd9b30SMilanka Ringwald 
1135a4cd9b30SMilanka Ringwald 						cptr->ticks++;
1136a4cd9b30SMilanka Ringwald 
1137a4cd9b30SMilanka Ringwald 						if( cptr->replen<=2 )
1138a4cd9b30SMilanka Ringwald 						{
1139a4cd9b30SMilanka Ringwald 							if( (cptr->samppos>>10) >= (cptr->length) )
1140a4cd9b30SMilanka Ringwald 							{
1141a4cd9b30SMilanka Ringwald 								cptr->length = 0;
1142a4cd9b30SMilanka Ringwald 								cptr->reppnt = 0;
1143a4cd9b30SMilanka Ringwald 
1144a4cd9b30SMilanka Ringwald 								if( cptr->length )
1145a4cd9b30SMilanka Ringwald 									cptr->samppos = cptr->samppos % (((unsigned long)cptr->length)<<10);
1146a4cd9b30SMilanka Ringwald 								else
1147a4cd9b30SMilanka Ringwald 									cptr->samppos = 0;
1148a4cd9b30SMilanka Ringwald 							}
1149a4cd9b30SMilanka Ringwald 						}
1150a4cd9b30SMilanka Ringwald 						else
1151a4cd9b30SMilanka Ringwald 						{
1152a4cd9b30SMilanka Ringwald 							if( (cptr->samppos>>10) >= (unsigned long)(cptr->replen+cptr->reppnt) )
1153a4cd9b30SMilanka Ringwald 							{
1154a4cd9b30SMilanka Ringwald 								cptr->samppos = ((unsigned long)(cptr->reppnt)<<10) + (cptr->samppos % ((unsigned long)(cptr->replen+cptr->reppnt)<<10));
1155a4cd9b30SMilanka Ringwald 							}
1156a4cd9b30SMilanka Ringwald 						}
1157a4cd9b30SMilanka Ringwald 
1158a4cd9b30SMilanka Ringwald 						k = cptr->samppos >> 10;
1159a4cd9b30SMilanka Ringwald 
1160a4cd9b30SMilanka Ringwald 						if( cptr->sampdata!=0 && ( ((j&3)==1) || ((j&3)==2) ) )
1161a4cd9b30SMilanka Ringwald 						{
1162a4cd9b30SMilanka Ringwald 							r += ( cptr->sampdata[k] *  cptr->volume );
1163a4cd9b30SMilanka Ringwald 						}
1164a4cd9b30SMilanka Ringwald 
1165a4cd9b30SMilanka Ringwald 						if( cptr->sampdata!=0 && ( ((j&3)==0) || ((j&3)==3) ) )
1166a4cd9b30SMilanka Ringwald 						{
1167a4cd9b30SMilanka Ringwald 							l += ( cptr->sampdata[k] *  cptr->volume );
1168a4cd9b30SMilanka Ringwald 						}
1169a4cd9b30SMilanka Ringwald 
1170a4cd9b30SMilanka Ringwald 						if( trkbuf && !state_remaining_steps )
1171a4cd9b30SMilanka Ringwald 						{
1172a4cd9b30SMilanka Ringwald 							if( trkbuf->nb_of_state < trkbuf->nb_max_of_state )
1173a4cd9b30SMilanka Ringwald 							{
1174a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].number_of_tracks = modctx->number_of_channels;
1175a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].buf_index = i;
1176a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern = modctx->song.patterntable[modctx->tablepos];
1177a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_pos = modctx->patternpos / modctx->number_of_channels;
1178a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].cur_pattern_table_pos = modctx->tablepos;
1179a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].bpm = modctx->bpm;
1180a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].speed = modctx->song.speed;
1181a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_effect = cptr->effect_code;
1182a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_parameffect = cptr->parameffect;
1183a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_period = finalperiod;
1184a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].cur_volume = cptr->volume;
1185a4cd9b30SMilanka Ringwald 								trkbuf->track_state_buf[trkbuf->nb_of_state].tracks[j].instrument_number = (unsigned char)cptr->sampnum;
1186a4cd9b30SMilanka Ringwald 							}
1187a4cd9b30SMilanka Ringwald 						}
1188a4cd9b30SMilanka Ringwald 					}
1189a4cd9b30SMilanka Ringwald 				}
1190a4cd9b30SMilanka Ringwald 
1191a4cd9b30SMilanka Ringwald 				if( trkbuf && !state_remaining_steps )
1192a4cd9b30SMilanka Ringwald 				{
1193a4cd9b30SMilanka Ringwald 					state_remaining_steps = trkbuf->sample_step;
1194a4cd9b30SMilanka Ringwald 
1195a4cd9b30SMilanka Ringwald 					if(trkbuf->nb_of_state < trkbuf->nb_max_of_state)
1196a4cd9b30SMilanka Ringwald 						trkbuf->nb_of_state++;
1197a4cd9b30SMilanka Ringwald 				}
1198a4cd9b30SMilanka Ringwald 				else
1199a4cd9b30SMilanka Ringwald 				{
1200a4cd9b30SMilanka Ringwald 					state_remaining_steps--;
1201a4cd9b30SMilanka Ringwald 				}
1202a4cd9b30SMilanka Ringwald 
1203a4cd9b30SMilanka Ringwald 				tl = (short)l;
1204a4cd9b30SMilanka Ringwald 				tr = (short)r;
1205a4cd9b30SMilanka Ringwald 
1206a4cd9b30SMilanka Ringwald 				if ( modctx->filter )
1207a4cd9b30SMilanka Ringwald 				{
1208a4cd9b30SMilanka Ringwald 					// Filter
1209a4cd9b30SMilanka Ringwald 					l = (l+ll)>>1;
1210a4cd9b30SMilanka Ringwald 					r = (r+lr)>>1;
1211a4cd9b30SMilanka Ringwald 				}
1212a4cd9b30SMilanka Ringwald 
1213a4cd9b30SMilanka Ringwald 				if ( modctx->stereo_separation == 1 )
1214a4cd9b30SMilanka Ringwald 				{
1215a4cd9b30SMilanka Ringwald 					// Left & Right Stereo panning
1216a4cd9b30SMilanka Ringwald 					l = (l+(r>>1));
1217a4cd9b30SMilanka Ringwald 					r = (r+(l>>1));
1218a4cd9b30SMilanka Ringwald 				}
1219a4cd9b30SMilanka Ringwald 
1220a4cd9b30SMilanka Ringwald 				// Level limitation
1221a4cd9b30SMilanka Ringwald 				if( l > 32767 ) l = 32767;
1222a4cd9b30SMilanka Ringwald 				if( l < -32768 ) l = -32768;
1223a4cd9b30SMilanka Ringwald 				if( r > 32767 ) r = 32767;
1224a4cd9b30SMilanka Ringwald 				if( r < -32768 ) r = -32768;
1225a4cd9b30SMilanka Ringwald 
1226a4cd9b30SMilanka Ringwald 				// Store the final sample.
1227a4cd9b30SMilanka Ringwald 				outbuffer[(i*2)]   = l;
1228a4cd9b30SMilanka Ringwald 				outbuffer[(i*2)+1] = r;
1229a4cd9b30SMilanka Ringwald 
1230a4cd9b30SMilanka Ringwald 				ll = tl;
1231a4cd9b30SMilanka Ringwald 				lr = tr;
1232a4cd9b30SMilanka Ringwald 
1233a4cd9b30SMilanka Ringwald 			}
1234a4cd9b30SMilanka Ringwald 
1235a4cd9b30SMilanka Ringwald 			modctx->last_l_sample = ll;
1236a4cd9b30SMilanka Ringwald 			modctx->last_r_sample = lr;
1237a4cd9b30SMilanka Ringwald 
1238a4cd9b30SMilanka Ringwald 			modctx->samplenb = modctx->samplenb+nbsample;
1239a4cd9b30SMilanka Ringwald 		}
1240a4cd9b30SMilanka Ringwald 		else
1241a4cd9b30SMilanka Ringwald 		{
1242a4cd9b30SMilanka Ringwald 			for (i = 0; i < nbsample; i++)
1243a4cd9b30SMilanka Ringwald 			{
1244a4cd9b30SMilanka Ringwald 				// Mod not loaded. Return blank buffer.
1245a4cd9b30SMilanka Ringwald 				outbuffer[(i*2)]   = 0;
1246a4cd9b30SMilanka Ringwald 				outbuffer[(i*2)+1] = 0;
1247a4cd9b30SMilanka Ringwald 			}
1248a4cd9b30SMilanka Ringwald 
1249a4cd9b30SMilanka Ringwald 			if(trkbuf)
1250a4cd9b30SMilanka Ringwald 			{
1251a4cd9b30SMilanka Ringwald 				trkbuf->nb_of_state = 0;
1252a4cd9b30SMilanka Ringwald 				trkbuf->cur_rd_index = 0;
1253a4cd9b30SMilanka Ringwald 				trkbuf->name[0] = 0;
1254a4cd9b30SMilanka Ringwald 				memclear(trkbuf->track_state_buf,0,sizeof(tracker_state) * trkbuf->nb_max_of_state);
1255a4cd9b30SMilanka Ringwald 				memclear(trkbuf->instruments,0,sizeof(trkbuf->instruments));
1256a4cd9b30SMilanka Ringwald 			}
1257a4cd9b30SMilanka Ringwald 		}
1258a4cd9b30SMilanka Ringwald 	}
1259a4cd9b30SMilanka Ringwald }
1260a4cd9b30SMilanka Ringwald 
1261a4cd9b30SMilanka Ringwald void hxcmod_unload( modcontext * modctx )
1262a4cd9b30SMilanka Ringwald {
1263a4cd9b30SMilanka Ringwald 	if(modctx)
1264a4cd9b30SMilanka Ringwald 	{
1265a4cd9b30SMilanka Ringwald 		memclear(&modctx->song,0,sizeof(modctx->song));
1266a4cd9b30SMilanka Ringwald 		memclear(&modctx->sampledata,0,sizeof(modctx->sampledata));
1267a4cd9b30SMilanka Ringwald 		memclear(&modctx->patterndata,0,sizeof(modctx->patterndata));
1268a4cd9b30SMilanka Ringwald 		modctx->tablepos = 0;
1269a4cd9b30SMilanka Ringwald 		modctx->patternpos = 0;
1270a4cd9b30SMilanka Ringwald 		modctx->patterndelay  = 0;
1271a4cd9b30SMilanka Ringwald 		modctx->jump_loop_effect = 0;
1272a4cd9b30SMilanka Ringwald 		modctx->bpm = 0;
1273a4cd9b30SMilanka Ringwald 		modctx->patternticks = 0;
1274a4cd9b30SMilanka Ringwald 		modctx->patterntickse = 0;
1275a4cd9b30SMilanka Ringwald 		modctx->patternticksaim = 0;
1276a4cd9b30SMilanka Ringwald 		modctx->sampleticksconst = 0;
1277a4cd9b30SMilanka Ringwald 
1278a4cd9b30SMilanka Ringwald 		modctx->samplenb = 0;
1279a4cd9b30SMilanka Ringwald 
1280a4cd9b30SMilanka Ringwald 		memclear(modctx->channels,0,sizeof(modctx->channels));
1281a4cd9b30SMilanka Ringwald 
1282a4cd9b30SMilanka Ringwald 		modctx->number_of_channels = 0;
1283a4cd9b30SMilanka Ringwald 
1284a4cd9b30SMilanka Ringwald 		modctx->mod_loaded = 0;
1285a4cd9b30SMilanka Ringwald 
1286a4cd9b30SMilanka Ringwald 		modctx->last_r_sample = 0;
1287a4cd9b30SMilanka Ringwald 		modctx->last_l_sample = 0;
1288a4cd9b30SMilanka Ringwald 	}
1289a4cd9b30SMilanka Ringwald }
1290