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