Mercurial > hg > dmlib
annotate jssplr.c @ 61:a33e47232161
Silence some "unused parameter" warnings.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 01 Oct 2012 09:49:10 +0300 |
parents | e0e470c3fc8e |
children | ff0fe1d1ab3d |
rev | line source |
---|---|
0 | 1 /* |
2 * miniJSS - Module playing routines | |
3 * Programmed and designed by Matti 'ccr' Hamalainen | |
4 * (C) Copyright 2006-2009 Tecnic Software productions (TNSP) | |
5 */ | |
6 #include "jssplr.h" | |
7 #include <string.h> | |
8 #include <stdlib.h> | |
9 | |
10 // FIXME!! FIX ME! | |
11 #include <math.h> | |
12 | |
13 /* Miscellaneous tables | |
14 */ | |
15 #define jmpNSineTable (256) | |
16 static int *jmpSineTable = NULL; | |
17 | |
18 | |
19 static const Sint16 jmpXMAmigaPeriodTab[13 * 8] = { | |
20 907, 900, 894, 887, 881, 875, 868, 862, 856, 850, 844, 838, | |
21 832, 826, 820, 814, 808, 802, 796, 791, 785, 779, 774, 768, | |
22 762, 757, 752, 746, 741, 736, 730, 725, 720, 715, 709, 704, | |
23 699, 694, 689, 684, 678, 675, 670, 665, 660, 655, 651, 646, | |
24 640, 636, 632, 628, 623, 619, 614, 610, 604, 601, 597, 592, | |
25 588, 584, 580, 575, 570, 567, 563, 559, 555, 551, 547, 543, | |
26 538, 535, 532, 528, 524, 520, 516, 513, 508, 505, 502, 498, | |
27 494, 491, 487, 484, 480, 477, 474, 470, 467, 463, 460, 457, | |
28 | |
29 453, 450, 447, 443, 440, 437, 434, 431 | |
30 }; | |
31 | |
32 | |
33 #define jmpNMODEffectTable (36) | |
34 static const char jmpMODEffectTable[jmpNMODEffectTable] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
35 | |
36 | |
37 /* Helper functions | |
38 */ | |
39 int jmpNoteToAmigaPeriod(int note, int finetune) | |
40 { | |
41 int tmp = (note + finetune + 8); | |
42 if (tmp < 0) tmp = 0; else | |
43 if (tmp > 103) tmp = 103; | |
44 return jmpXMAmigaPeriodTab[tmp]; | |
45 } | |
46 | |
47 | |
48 static int jmpGetPeriodFromNote(JSSPlayer *mp, int note, int finetune) | |
49 { | |
50 int res; | |
51 | |
52 if (JMPGETMODFLAGS(mp, jmdfAmigaPeriods)) | |
53 { | |
54 int mfinetune = finetune / 16, | |
55 mnote = (note % 12) * 8, | |
56 moctave = note / 12, | |
57 period1, period2; | |
58 | |
59 period1 = jmpNoteToAmigaPeriod(mnote, mfinetune); | |
60 | |
61 if (finetune < 0) | |
62 { | |
63 mfinetune--; | |
64 finetune = -finetune; | |
65 } else | |
66 mfinetune++; | |
67 | |
68 period2 = jmpNoteToAmigaPeriod(mnote, mfinetune); | |
69 | |
70 mfinetune = finetune & 15; | |
71 period1 *= (16 - mfinetune); | |
72 period2 *= mfinetune; | |
73 | |
74 res = ((period1 + period2) * 2) >> moctave; | |
75 | |
76 //fprintf(stderr, "jmpGetAmigaPeriod(%d, %d) = %d\n", note, finetune, res); | |
77 } | |
78 else | |
79 { | |
80 //fprintf(stderr, "jmpGetLinearPeriod(%d, %d) = %d\n", note, finetune, res); | |
81 //res = ((120 - note) << 6) - (finetune / 2); | |
82 res = 7680 - (note * 64) - (finetune / 2); | |
83 if (res < 1) res = 1; | |
84 } | |
85 | |
86 return res; | |
87 } | |
88 | |
89 | |
90 static void jmpCSetPitch(JSSPlayer *mp, int channel, int value) | |
91 { | |
92 assert(mp != NULL); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
93 assert(mp->device != NULL); |
0 | 94 |
95 if (value > 0) | |
96 { | |
97 if (JMPGETMODFLAGS(mp, jmdfAmigaPeriods)) | |
98 { | |
99 // Frequency = 8363*1712 / Period | |
100 //fprintf(stderr, "jmpCSetPitch::AMIGA(%d, %d)\n", channel, value); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
101 jvmSetFreq(mp->device, channel, 14317456.0f / (double) value); |
0 | 102 } |
103 else | |
104 { | |
105 // Frequency = Frequency = 8363*2^((6*12*16*4 - Period) / (12*16*4)) | |
106 //fprintf(stderr, "jmpCSetPitch::Linear(%d, %d)\n", channel, value); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
107 jvmSetFreq(mp->device, channel, |
0 | 108 8363.0f * pow(2.0f, (4608.0f - (double) value) / 768.0f)); |
109 } | |
110 } | |
111 } | |
112 | |
113 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
114 static void jmpCSetVolume(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int volume) |
0 | 115 { |
116 assert(mp != NULL); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
117 assert(mp->device != NULL); |
0 | 118 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
119 if (volume < mpMinVol) volume = mpMinVol; else |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
120 if (volume > mpMaxVol) volume = mpMaxVol; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
121 |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
122 //fprintf(stderr, "chn %d: vol=%d, fad=%d, env=%d\n", channel, volume, chn->iCFadeOutVol, chn->iCVolEnv); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
123 |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
124 jvmSetVolume(mp->device, channel, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
125 (chn->iCFadeOutVol * chn->iCVolEnv * volume) / (16 * 65536)); |
0 | 126 } |
127 | |
128 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
129 static void jmpCSetPanning(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int panning) |
0 | 130 { |
131 assert(mp != NULL); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
132 assert(mp->device != NULL); |
0 | 133 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
134 jvmSetPan(mp->device, channel, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
135 panning + (((chn->iCPanEnv - 32) * (128 - abs(panning - 128))) / 32)); |
0 | 136 } |
137 | |
138 | |
139 static void jmpCSetPosition(JSSPlayer * mp, int channel, int value) | |
140 { | |
141 assert(mp != NULL); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
142 assert(mp->device != NULL); |
0 | 143 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
144 jvmSetPos(mp->device, channel, value); |
0 | 145 } |
146 | |
147 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
148 static int jmpFindEnvPoint(JSSEnvelope * env, const int pos) |
0 | 149 { |
150 int i; | |
151 | |
152 for (i = 0; i < env->npoints - 1; i++) | |
153 { | |
154 if (env->points[i].frame <= pos && | |
155 env->points[i + 1].frame >= pos) | |
156 return i; | |
157 } | |
158 | |
159 return -1; | |
160 } | |
161 | |
162 | |
163 static void jmpExecEnvelope(JSSEnvelope * env, BOOL keyOff, int * frames, BOOL * doExec, int * result) | |
164 { | |
165 int currPoint, delta; | |
166 JSSEnvelopePoint *ipf1, *ipf2; | |
167 | |
168 // OK, find the current point based on frame | |
169 currPoint = jmpFindEnvPoint(env, *frames); | |
170 | |
171 // Check if the envelope has ended | |
172 if (currPoint < 0 && (env->flags & jenvfLooped) == 0) | |
173 { | |
174 *doExec = FALSE; | |
175 return; | |
176 } | |
177 | |
178 // Do the envelope looping here, if needed | |
179 if ((env->flags & jenvfLooped) && *frames >= env->points[env->loopE].frame) | |
180 { | |
181 currPoint = env->loopS; | |
182 *frames = env->points[currPoint].frame; | |
183 } | |
184 | |
185 // If the current point is OK, then process the envelope | |
186 if (currPoint >= 0) | |
187 { | |
188 // Linearly interpolate the value for given frame | |
189 ipf1 = &env->points[currPoint]; | |
190 ipf2 = &env->points[currPoint + 1]; | |
191 | |
192 delta = (ipf2->frame - ipf1->frame); | |
193 if (delta > 0) | |
194 *result = ipf1->value + ((ipf2->value - ipf1->value) * (*frames - ipf1->frame)) / delta; | |
195 else | |
196 *result = ipf1->value; | |
197 } | |
198 | |
199 // The frame counter IS processed even if the envelope is not! | |
200 if ((env->flags & jenvfSustain) && currPoint == env->sustain && | |
201 env->points[currPoint].frame == env->points[env->sustain].frame) { | |
202 if (keyOff) (*frames)++; | |
203 } else | |
204 (*frames)++; | |
205 } | |
206 | |
207 | |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
208 static void jmpProcessExtInstrument(JSSPlayerChannel *chn, int channel) |
0 | 209 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
210 JSSExtInstrument *inst = chn->iCExtInstrument; |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
211 (void) channel; |
0 | 212 |
213 // Get the instrument for envelope data | |
214 if (!inst) return; | |
215 | |
216 // Process the autovibrato | |
217 /* | |
218 FIXME fix me FIX me!!! todo. | |
219 */ | |
220 | |
221 // Process the volume envelope | |
222 if (inst->volumeEnv.flags & jenvfUsed) | |
223 { | |
224 // Process the instrument volume fadeout | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
225 if (chn->iCKeyOff && chn->iCFadeOutVol > 0 && inst->fadeOut > 0) |
0 | 226 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
227 int tmp = chn->iCFadeOutVol - inst->fadeOut; |
0 | 228 if (tmp < 0) tmp = 0; |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
229 chn->iCFadeOutVol = tmp; |
0 | 230 |
231 JMPSETNDFLAGS(cdfNewVolume); | |
232 } | |
233 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
234 if (chn->iCVolEnv_Exec) |
0 | 235 { |
236 // Execute the volume envelope | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
237 jmpExecEnvelope(&(inst->volumeEnv), |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
238 chn->iCKeyOff, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
239 &(chn->iCVolEnv_Frames), &(chn->iCVolEnv_Exec), |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
240 &(chn->iCVolEnv)); |
0 | 241 |
242 JMPSETNDFLAGS(cdfNewVolume); | |
243 } | |
244 } | |
245 else | |
246 { | |
247 // If the envelope is not used, set max volume | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
248 if (chn->iCVolEnv != mpMaxVol) |
0 | 249 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
250 chn->iCVolEnv = mpMaxVol; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
251 chn->iCFadeOutVol = mpMaxFadeoutVol; |
0 | 252 JMPSETNDFLAGS(cdfNewVolume); |
253 } | |
254 } | |
255 | |
256 // Process the panning envelope | |
257 if (inst->panningEnv.flags & jenvfUsed) | |
258 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
259 if (chn->iCPanEnv_Exec) |
0 | 260 { |
261 // Execute the panning envelope | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
262 jmpExecEnvelope(&(inst->panningEnv), chn->iCKeyOff, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
263 &(chn->iCPanEnv_Frames), &(chn->iCPanEnv_Exec), |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
264 &(chn->iCPanEnv)); |
0 | 265 |
266 JMPSETNDFLAGS(cdfNewPanPos); | |
267 } | |
268 } | |
269 else | |
270 { | |
271 // If the envelope is not used, set center panning | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
272 if (chn->iCPanEnv != mpPanCenter) |
0 | 273 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
274 chn->iCPanEnv = mpPanCenter; |
0 | 275 JMPSETNDFLAGS(cdfNewPanPos); |
276 } | |
277 } | |
278 } | |
279 | |
280 | |
281 /* | |
282 * The player | |
283 */ | |
284 JSSPlayer *jmpInit(JSSMixer *pDevice) | |
285 { | |
286 JSSPlayer *mp; | |
287 | |
288 // Initialize global tables | |
289 if (jmpSineTable == NULL) | |
290 { | |
291 int i; | |
292 if ((jmpSineTable = dmMalloc(jmpNSineTable * sizeof(int))) == NULL) | |
293 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate memory for sinus table.\n"); | |
294 | |
295 for (i = 0; i < 256; i++) | |
296 { | |
297 float f = ((float) i * M_PI * 2.0f) / 256.0f; | |
298 jmpSineTable[i] = (int) (sin(f) * 2048.0f); | |
299 } | |
300 } | |
301 | |
302 // Allocate a player structure | |
303 mp = dmMalloc0(sizeof(JSSPlayer)); | |
304 if (!mp) | |
305 JSSERROR(DMERR_MALLOC, NULL, "Could not allocate memory for player structure.\n"); | |
306 | |
307 // Set variables | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
308 mp->device = pDevice; |
0 | 309 #ifdef JSS_SUP_THREADS |
310 mp->mutex = dmCreateMutex(); | |
311 #endif | |
312 | |
313 return mp; | |
314 } | |
315 | |
316 | |
317 int jmpClose(JSSPlayer * mp) | |
318 { | |
319 if (mp == NULL) | |
320 return DMERR_NULLPTR; | |
321 | |
322 // Stop player | |
323 jmpStop(mp); | |
324 | |
325 // Deallocate resources | |
326 #ifdef JSS_SUP_THREADS | |
327 dmDestroyMutex(mp->mutex); | |
328 #endif | |
329 | |
330 // Clear structure | |
331 memset(mp, 0, sizeof(JSSPlayer)); | |
332 dmFree(mp); | |
333 | |
334 return DMERR_OK; | |
335 } | |
336 | |
337 | |
338 /* Reset the envelopes for given channel. | |
339 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
340 static void jmpResetEnvelopes(JSSPlayerChannel *chn) |
0 | 341 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
342 chn->iCPanEnv_Frames = chn->iCVolEnv_Frames = 0; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
343 chn->iCPanEnv_Exec = chn->iCVolEnv_Exec = TRUE; |
0 | 344 } |
345 | |
346 | |
347 /* Clear module player structure | |
348 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
349 void jmpClearChannel(JSSPlayerChannel *chn) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
350 { |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
351 memset(chn, 0, sizeof(JSSPlayerChannel)); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
352 |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
353 chn->iCNote = jsetNotSet; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
354 chn->iCInstrumentN = jsetNotSet; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
355 chn->iCExtInstrumentN = jsetNotSet; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
356 chn->iCPanning = mpPanCenter; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
357 chn->iCPanEnv = mpPanCenter; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
358 } |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
359 |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
360 |
0 | 361 void jmpClearPlayer(JSSPlayer * mp) |
362 { | |
363 int i; | |
364 assert(mp != NULL); | |
365 JSS_LOCK(mp); | |
366 | |
367 // Initialize general variables | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
368 mp->patternDelay = 0; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
369 mp->newRowSet = FALSE; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
370 mp->newOrderSet = FALSE; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
371 mp->tick = jsetNotSet; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
372 mp->row = 0; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
373 mp->lastPatLoopRow = 0; |
0 | 374 |
375 // Initialize channel data | |
376 for (i = 0; i < jsetNChannels; i++) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
377 jmpClearChannel(&mp->channels[i]); |
0 | 378 |
379 JSS_UNLOCK(mp); | |
380 } | |
381 | |
382 | |
383 /* Set module | |
384 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
385 void jmpSetModule(JSSPlayer * mp, JSSModule * module) |
0 | 386 { |
387 assert(mp != NULL); | |
388 JSS_LOCK(mp); | |
389 | |
390 jmpStop(mp); | |
391 jmpClearPlayer(mp); | |
392 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
393 mp->module = module; |
0 | 394 |
395 JSS_UNLOCK(mp); | |
396 } | |
397 | |
398 | |
399 /* Stop playing | |
400 */ | |
401 void jmpStop(JSSPlayer * mp) | |
402 { | |
403 assert(mp != NULL); | |
404 JSS_LOCK(mp); | |
405 | |
406 if (mp->isPlaying) | |
407 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
408 jvmRemoveCallback(mp->device); |
0 | 409 mp->isPlaying = FALSE; |
410 } | |
411 | |
412 JSS_UNLOCK(mp); | |
413 } | |
414 | |
415 | |
416 /* Resume playing | |
417 */ | |
418 void jmpResume(JSSPlayer * mp) | |
419 { | |
420 assert(mp != NULL); | |
421 JSS_LOCK(mp); | |
422 | |
423 if (!mp->isPlaying) | |
424 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
425 int result = jvmSetCallback(mp->device, jmpExec, (void *) mp); |
0 | 426 if (result != DMERR_OK) |
427 JSSERROR(result,, "Could not initialize callback for player.\n"); | |
428 | |
429 mp->isPlaying = TRUE; | |
430 } | |
431 | |
432 JSS_UNLOCK(mp); | |
433 } | |
434 | |
435 | |
436 /* Sets new order using given value as reference. | |
437 * Jumps over skip-points and invalid values, loops | |
438 * to first order if enabled. | |
439 */ | |
440 static void jmpSetNewOrder(JSSPlayer * mp, int order) | |
441 { | |
442 BOOL orderOK; | |
443 int pattern; | |
444 | |
445 pattern = jsetOrderEnd; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
446 mp->order = jsetNotSet; |
0 | 447 orderOK = FALSE; |
448 | |
449 while (!orderOK) | |
450 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
451 if (order < 0 || order >= mp->module->norders) |
0 | 452 { |
453 jmpStop(mp); | |
454 orderOK = TRUE; | |
455 } | |
456 else | |
457 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
458 pattern = mp->module->orderList[order]; |
0 | 459 if (pattern == jsetOrderSkip) |
460 { | |
461 order++; | |
462 } | |
463 else | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
464 if (pattern >= mp->module->npatterns || pattern == jsetOrderEnd) |
0 | 465 { |
466 jmpStop(mp); | |
467 orderOK = TRUE; | |
468 } | |
469 else | |
470 { | |
471 // All OK | |
472 orderOK = TRUE; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
473 mp->pattern = mp->module->patterns[pattern]; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
474 mp->npattern = pattern; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
475 mp->order = order; |
0 | 476 } |
477 } | |
478 } | |
479 } | |
480 | |
481 | |
482 /* Set new tempo-value of the player. | |
483 */ | |
484 void jmpSetTempo(JSSPlayer * mp, int tempo) | |
485 { | |
486 assert(mp != NULL); | |
487 JSS_LOCK(mp); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
488 assert(mp->device != NULL); |
0 | 489 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
490 mp->tempo = tempo; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
491 jvmSetCallbackFreq(mp->device, (tempo * 2) / 5); |
0 | 492 JSS_UNLOCK(mp); |
493 } | |
494 | |
495 | |
496 void jmpClearChannels(JSSPlayer * mp) | |
497 { | |
498 int i; | |
499 assert(mp != NULL); | |
500 JSS_LOCK(mp); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
501 assert(mp->device != NULL); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
502 assert(mp->module != NULL); |
0 | 503 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
504 for (i = 0; i < mp->module->nchannels; i++) |
0 | 505 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
506 jvmStop(mp->device, i); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
507 jvmClear(mp->device, i); |
0 | 508 } |
509 | |
510 JSS_UNLOCK(mp); | |
511 } | |
512 | |
513 | |
514 /* Starts playing module from a given ORDER. | |
515 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
516 int jmpPlayOrder(JSSPlayer * mp, int order) |
0 | 517 { |
518 int result; | |
519 assert(mp != NULL); | |
520 | |
521 JSS_LOCK(mp); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
522 assert(mp->module != NULL); |
0 | 523 |
524 // Stop if already playing | |
525 jmpStop(mp); | |
526 jmpClearChannels(mp); | |
527 | |
528 // Check starting order | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
529 if (order < 0 || order >= mp->module->norders) |
0 | 530 { |
531 JSS_UNLOCK(mp); | |
532 JSSERROR(DMERR_INVALID_ARGS, DMERR_INVALID_ARGS, "Invalid playing startorder given.\n"); | |
533 } | |
534 | |
535 // Initialize playing | |
536 jmpClearPlayer(mp); | |
537 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
538 jmpSetNewOrder(mp, order); |
0 | 539 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
540 if (mp->order == jsetNotSet) |
0 | 541 { |
542 JSS_UNLOCK(mp); | |
543 JSSERROR(DMERR_NOT_SUPPORTED, DMERR_NOT_SUPPORTED, | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
544 "Could not start playing from given order #%i\n", order); |
0 | 545 } |
546 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
547 mp->speed = mp->module->defSpeed; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
548 jmpSetTempo(mp, mp->module->defTempo); |
0 | 549 |
550 // Set callback | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
551 result = jvmSetCallback(mp->device, jmpExec, (void *) mp); |
0 | 552 if (result != DMERR_OK) |
553 { | |
554 JSS_UNLOCK(mp); | |
555 JSSERROR(result, result, "Could not initialize callback for player.\n"); | |
556 } | |
557 | |
558 mp->isPlaying = TRUE; | |
559 | |
560 JSS_UNLOCK(mp); | |
561 return 0; | |
562 } | |
563 | |
564 | |
565 /* Play given pattern | |
566 */ | |
567 int jmpPlayPattern(JSSPlayer * mp, int pattern) | |
568 { | |
569 int result; | |
570 assert(mp != NULL); | |
571 JSS_LOCK(mp); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
572 assert(mp->module != NULL); |
0 | 573 |
574 // Stop if already playing | |
575 jmpStop(mp); | |
576 jmpClearChannels(mp); | |
577 | |
578 // Initialize playing | |
579 jmpClearPlayer(mp); | |
580 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
581 mp->npattern = pattern; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
582 mp->speed = mp->module->defSpeed; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
583 jmpSetTempo(mp, mp->module->defTempo); |
0 | 584 |
585 // Set callback | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
586 result = jvmSetCallback(mp->device, jmpExec, (void *) mp); |
0 | 587 if (result != DMERR_OK) |
588 { | |
589 JSS_UNLOCK(mp); | |
590 JSSERROR(result, result, "Could not initialize callback for player.\n"); | |
591 } | |
592 | |
593 mp->isPlaying = TRUE; | |
594 | |
595 JSS_UNLOCK(mp); | |
596 return 0; | |
597 } | |
598 | |
599 | |
600 /* Set volume for given module channel. | |
601 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
602 static void jmpSetVolume(JSSPlayerChannel * chn, int channel, int volume) |
0 | 603 { |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
604 (void) channel; |
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
605 |
0 | 606 // Check values |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
607 if (volume < mpMinVol) volume = mpMinVol; else |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
608 if (volume > mpMaxVol) volume = mpMaxVol; |
0 | 609 |
610 // Set the volume | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
611 chn->iCVolume = volume; |
0 | 612 JMPSETNDFLAGS(cdfNewVolume); |
613 } | |
614 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
615 #define jmpChangeVolume(Q, Z, X) jmpSetVolume(Q, Z, chn->iCVolume + (X)) |
0 | 616 |
617 | |
618 /* Change the pitch of given channel by ADelta. | |
619 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
620 static void jmpChangePitch(JSSPlayerChannel *chn, int channel, int delta) |
0 | 621 { |
622 int value; | |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
623 (void) channel; |
0 | 624 |
625 // Calculate new pitch and check it | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
626 value = chn->iCPitch + delta; |
0 | 627 if (value < 0) |
628 value = 0; | |
629 | |
630 // Set the new pitch | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
631 chn->iCPitch = value; |
0 | 632 JMPSETNDFLAGS(cdfNewPitch); |
633 } | |
634 | |
635 | |
636 /* Do a note portamento (pitch slide) effect for given module channel. | |
637 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
638 static void jmpDoPortamento(JSSPlayerChannel * chn, int channel) |
0 | 639 { |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
640 (void) channel; |
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
641 |
0 | 642 // Check for zero parameter |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
643 if (chn->iLastPortaToNoteParam == 0) |
0 | 644 { |
645 JMPSETNDFLAGS(cdfNewPitch); | |
646 return; | |
647 } | |
648 | |
649 /* Slide the pitch of channel to the destination value | |
650 * with speed of iLastPortaToNoteParam[] * 4 and stop when it equals. | |
651 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
652 if (chn->iCPitch != chn->iLastPortaToNotePitch) |
0 | 653 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
654 if (chn->iCPitch < chn->iLastPortaToNotePitch) |
0 | 655 { |
656 // Increase pitch UP | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
657 jmpChangePitch(chn, channel, chn->iLastPortaToNoteParam * 4); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
658 if (chn->iCPitch > chn->iLastPortaToNotePitch) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
659 chn->iCPitch = chn->iLastPortaToNotePitch; |
0 | 660 } |
661 else | |
662 { | |
663 // Decrease pitch DOWN | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
664 jmpChangePitch(chn, channel, -(chn->iLastPortaToNoteParam * 4)); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
665 if (chn->iCPitch < chn->iLastPortaToNotePitch) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
666 chn->iCPitch = chn->iLastPortaToNotePitch; |
0 | 667 } |
668 } | |
669 } | |
670 | |
671 | |
672 /* Do a tremolo effect for given module channel. | |
673 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
674 static void jmpDoTremolo(JSSPlayer * mp, JSSPlayerChannel *chn, int channel) |
0 | 675 { |
676 int delta, pos, depth; | |
677 | |
678 // Check settings | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
679 if (chn->iTremoloDepth == 0 || chn->iTremoloSpeed == 0) |
0 | 680 return; |
681 | |
682 // Get position of tremolo waveform | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
683 pos = chn->iTremoloPos & 255; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
684 depth = chn->iTremoloDepth; |
0 | 685 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
686 switch (chn->iTremoloWC & 3) |
0 | 687 { |
688 case 0: // Sine-wave | |
689 delta = (jmpSineTable[pos] * depth) / 2048; | |
690 break; | |
691 | |
692 case 1: // Ramp down | |
693 delta = ((pos - 128) * depth) / 128; | |
694 break; | |
695 | |
696 case 2: // Square | |
697 delta = (((pos & 128) - 64) * depth) / 64; | |
698 break; | |
699 | |
700 default: | |
701 return; | |
702 } | |
703 | |
704 // Set the new volume | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
705 jmpCSetVolume(mp, chn, channel, chn->iCVolume + delta); |
0 | 706 |
707 // Advance tremolo waveform position | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
708 chn->iTremoloPos += chn->iTremoloSpeed; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
709 if (chn->iTremoloPos > 255) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
710 chn->iTremoloPos = 0; |
0 | 711 } |
712 | |
713 | |
714 /* Do a vibrato effect for given module channel. | |
715 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
716 static void jmpDoVibrato(JSSPlayer * mp, JSSPlayerChannel *chn, int channel) |
0 | 717 { |
718 int delta, pos, depth; | |
719 | |
720 // Check settings | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
721 if (chn->iVibratoDepth == 0 || chn->iVibratoSpeed == 0) |
0 | 722 return; |
723 | |
724 // Get position of vibrato waveform | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
725 pos = chn->iVibratoPos & 255; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
726 depth = chn->iVibratoDepth; |
0 | 727 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
728 switch (chn->iVibratoWC & 3) |
0 | 729 { |
730 case 0: // Sine-wave | |
731 delta = (jmpSineTable[pos] * depth) / 2048; | |
732 break; | |
733 | |
734 case 1: // Ramp down | |
735 delta = ((pos - 128) * depth) / 16; | |
736 break; | |
737 | |
738 case 2: // Square | |
739 delta = (((pos & 128) - 64) * depth) / 8; | |
740 break; | |
741 | |
742 default: | |
743 return; | |
744 } | |
745 | |
746 // Set the new frequency | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
747 jmpCSetPitch(mp, channel, chn->iCPitch + delta); |
0 | 748 |
749 // Advance vibrato waveform position | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
750 chn->iVibratoPos += chn->iVibratoSpeed; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
751 if (chn->iVibratoPos > 255) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
752 chn->iVibratoPos = 0; |
0 | 753 } |
754 | |
755 | |
756 /* Do a volume slide effect for given module channel. | |
757 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
758 static void jmpDoVolumeSlide(JSSPlayerChannel * chn, int channel, int param) |
0 | 759 { |
760 int paramX, paramY; | |
761 | |
762 JMPMAKEPARAM(param, paramX, paramY) | |
763 | |
764 if (paramY == 0) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
765 jmpChangeVolume(chn, channel, paramX); |
0 | 766 if (paramX == 0) |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
767 jmpChangeVolume(chn, channel, -paramY); |
0 | 768 } |
769 | |
770 | |
771 /* Execute a pattern loop effect/command for given module channel. | |
772 * | |
773 * This routine works for most of the supported formats, as they | |
774 * use the 'standard' implementation ascending from MOD. However, | |
775 * here is included also a slightly kludgy implementation of the | |
776 * FT2 patloop bug. | |
777 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
778 static void jmpDoPatternLoop(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int paramY) |
0 | 779 { |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
780 (void) channel; |
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
781 |
0 | 782 // Check what we need to do |
783 if (paramY > 0) | |
784 { | |
785 // SBx/E6x loops 'x' times | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
786 if (chn->iPatLoopCount == 1) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
787 chn->iPatLoopCount = 0; |
0 | 788 else |
789 { | |
790 // Check if we need to set the count | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
791 if (chn->iPatLoopCount == 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
792 chn->iPatLoopCount = (paramY + 1); |
0 | 793 |
794 // Loop to specified row | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
795 chn->iPatLoopCount--; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
796 mp->newRow = chn->iPatLoopRow; |
0 | 797 mp->newRowSet = TRUE; |
798 } | |
799 } | |
800 else | |
801 { | |
802 // SB0/E60 sets the loop start point | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
803 chn->iPatLoopRow = mp->row; |
0 | 804 |
805 // This is here because of the infamous FT2 patloop bug | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
806 mp->lastPatLoopRow = mp->row; |
0 | 807 } |
808 } | |
809 | |
810 | |
811 /* Do arpeggio effect | |
812 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
813 static void jmpDoArpeggio(JSSPlayer * mp, JSSPlayerChannel *chn, int channel, int paramY, int paramX) |
0 | 814 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
815 JSSInstrument *tempInst = chn->iCInstrument; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
816 |
0 | 817 if (tempInst) |
818 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
819 int tmp = chn->iCNote; |
0 | 820 if (tmp == jsetNotSet || tmp == jsetNoteOff) return; |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
821 switch (mp->tick & 3) |
0 | 822 { |
823 case 1: | |
824 tmp += paramX; | |
825 break; | |
826 case 2: | |
827 tmp += paramY; | |
828 break; | |
829 } | |
830 jmpCSetPitch(mp, channel, jmpGetPeriodFromNote(mp, tmp + tempInst->ERelNote, tempInst->EFineTune)); | |
831 } | |
832 } | |
833 | |
834 | |
835 /* | |
836 * Process pattern effects | |
837 */ | |
838 static void jmpProcessRowEffect(JSSPlayer * mp, int channel, JSSNote * currNote) | |
839 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
840 JSSPlayerChannel *chn = &(mp->channels[channel]); |
0 | 841 int param, paramX, paramY; |
842 char effect; | |
843 | |
844 param = currNote->param; | |
845 JMPMAKEPARAM(param, paramX, paramY); | |
846 JMPGETEFFECT(effect, currNote->effect); | |
847 | |
848 switch (effect) | |
849 { | |
850 case '0': // 0xy = Arpeggio | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
851 jmpDoArpeggio(mp, chn, channel, paramX, paramY); |
0 | 852 break; |
853 | |
854 case 'W': // Used widely in demo-music as MIDAS Sound System sync-command | |
855 case 'Q': // SoundTracker/OpenCP: Qxx = Set LP filter resonance | |
856 case 'Z': // SoundTracker/OpenCP: Zxx = Set LP filter cutoff freq | |
857 break; | |
858 | |
859 case '1': | |
860 case '2': // 1xy = Portamento Up, 2xy = Portamento Down : IMPL.VERIFIED | |
861 if (param) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
862 chn->iLastPortaParam = param; |
0 | 863 break; |
864 | |
865 case '3': // 3xy = Porta To Note | |
866 if (param) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
867 chn->iLastPortaToNoteParam = param; |
0 | 868 |
869 if (currNote->note != jsetNotSet && currNote->note != jsetNoteOff) { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
870 chn->iLastPortaToNotePitch = chn->iCPitch; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
871 chn->iCPitch = chn->iCOldPitch; |
0 | 872 JMPUNSETNDFLAGS(cdfNewPitch | cdfNewInstr | cdfNewPanPos); |
873 } | |
874 break; | |
875 | |
876 case '4': // 4xy = Vibrato : IMPL.VERIFIED | |
877 if (paramX) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
878 chn->iVibratoSpeed = paramX; |
0 | 879 |
880 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
881 chn->iVibratoDepth = paramY; |
0 | 882 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
883 if ((chn->iVibratoWC & 4) == 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
884 chn->iVibratoPos = 0; |
0 | 885 break; |
886 | |
887 case '5': // 5xy = Portamento + Volume Slide | |
888 case '6': // 6xy = Vibrato + Volume slide | |
889 if (param) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
890 chn->iLastVolSlideParam = param; |
0 | 891 break; |
892 | |
893 case '7': // 7xy = Tremolo | |
894 if (paramX) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
895 chn->iTremoloSpeed = paramX; |
0 | 896 |
897 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
898 chn->iTremoloDepth = paramY; |
0 | 899 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
900 if ((chn->iTremoloWC & 4) == 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
901 chn->iTremoloPos = 0; |
0 | 902 break; |
903 | |
904 case '8': // 8xx = Set Panning | |
905 JMPDEBUG("Set Panning used, UNIMPLEMENTED"); | |
906 break; | |
907 | |
908 case '9': // 9xx = Set Sample Offset : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
909 if (chn->iCNewDataFlags & cdfNewPitch) |
30 | 910 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
911 chn->iCPosition = param * 0x100; |
0 | 912 JMPSETNDFLAGS(cdfNewPos); |
913 } | |
914 break; | |
915 | |
916 case 'A': // Axy = Volume Slide : IMPL.VERIFIED | |
917 if (param) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
918 chn->iLastVolSlideParam = param; |
0 | 919 break; |
920 | |
921 case 'B': // Bxx = Pattern Jump : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
922 mp->newOrder = param; |
0 | 923 mp->newOrderSet = TRUE; |
924 mp->jumpFlag = TRUE; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
925 mp->lastPatLoopRow = 0; |
0 | 926 break; |
927 | |
928 case 'C': // Cxx = Set Volume : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
929 jmpSetVolume(chn, channel, param); |
0 | 930 break; |
931 | |
932 case 'D': // Dxx = Pattern Break : IMPL.VERIFIED | |
933 // Compute the new row | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
934 mp->newRow = (paramX * 10) + paramY; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
935 if (mp->newRow >= mp->pattern->nrows) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
936 mp->newRow = 0; |
0 | 937 |
938 mp->newRowSet = TRUE; | |
939 | |
940 // Now we do some tricky tests | |
941 if (!mp->breakFlag && !mp->jumpFlag) { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
942 mp->newOrder = mp->order + 1; |
0 | 943 mp->newOrderSet = TRUE; |
944 } | |
945 | |
946 mp->breakFlag = TRUE; | |
947 break; | |
948 | |
949 case 'E': // Exy = Special Effects | |
950 switch (paramX) { | |
951 case 0x00: // E0x - Set filter (NOT SUPPORTED) | |
952 JMPDEBUG("Set Filter used, UNSUPPORTED"); | |
953 break; | |
954 | |
955 case 0x01: // E1x - Fine Portamento Up | |
956 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
957 chn->iCLastFinePortamentoUpParam = paramY; |
0 | 958 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
959 jmpChangePitch(chn, channel, -(chn->iCLastFinePortamentoUpParam * 4)); |
0 | 960 break; |
961 | |
962 case 0x02: // E2x - Fine Portamento Down | |
963 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
964 chn->iCLastFinePortamentoDownParam = paramY; |
0 | 965 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
966 jmpChangePitch(chn, channel, (chn->iCLastFinePortamentoDownParam * 4)); |
0 | 967 break; |
968 | |
969 case 0x03: // E3x - Glissando Control (NOT SUPPORTED) | |
970 break; | |
971 | |
972 case 0x04: // E4x - Set Vibrato waveform | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
973 chn->iVibratoWC = paramY; |
0 | 974 break; |
975 | |
976 case 0x05: // E5x - Set Finetune | |
977 JMPDEBUG("Set Finetune used, UNIMPLEMENTED"); | |
978 break; | |
979 | |
980 case 0x06: // E6x - Set Pattern Loop | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
981 jmpDoPatternLoop(mp, chn, channel, paramY); |
0 | 982 break; |
983 | |
984 case 0x07: // E7x - Set Tremolo waveform | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
985 chn->iTremoloWC = paramY; |
0 | 986 break; |
987 | |
988 case 0x08: // E8x - Set Pan Position | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
989 chn->iCPanning = (paramY * 16); |
0 | 990 JMPSETNDFLAGS(cdfNewPanPos); |
991 break; | |
992 | |
993 case 0x09: // E9x - Retrig note | |
994 JMPDEBUG("Retrig Note used, UNIMPLEMENTED"); | |
995 break; | |
996 | |
997 case 0x0a: // EAx - Fine Volumeslide Up | |
998 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
999 chn->iCLastFineVolumeslideUpParam = paramY; |
0 | 1000 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1001 jmpChangeVolume(chn, channel, chn->iCLastFineVolumeslideUpParam); |
0 | 1002 break; |
1003 | |
1004 case 0x0b: // EBx - Fine Volumeslide Down | |
1005 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1006 chn->iCLastFineVolumeslideDownParam = paramY; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1007 jmpChangeVolume(chn, channel, -(chn->iCLastFineVolumeslideDownParam)); |
0 | 1008 break; |
1009 | |
1010 case 0x0c: // ECx - Set Note Cut (NOT PROCESSED IN TICK0) | |
1011 break; | |
1012 | |
1013 case 0x0d: // EDx - Set Note Delay : IMPL.VERIFIED | |
1014 if (paramY > 0) | |
1015 { | |
1016 // Save the ND-flags, then clear | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1017 chn->iSaveNDFlags = chn->iCNewDataFlags; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1018 chn->iCNewDataFlags = 0; |
0 | 1019 // TODO .. does this only affect NOTE or also instrument? |
1020 } | |
1021 break; | |
1022 | |
1023 case 0x0e: // EEx - Set Pattern Delay : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1024 mp->patternDelay = paramY; |
0 | 1025 break; |
1026 | |
1027 case 0x0f: // EFx - Invert Loop (NOT SUPPORTED) | |
1028 JMPDEBUG("Invert Loop used, UNSUPPORTED"); | |
1029 break; | |
1030 | |
1031 default: | |
1032 JMPDEBUG("Unsupported special command used"); | |
1033 } | |
1034 break; | |
1035 | |
1036 case 'F': // Fxy = Set Speed / Tempo : IMPL.VERIFIED | |
1037 if (param > 0) | |
1038 { | |
1039 if (param < 0x20) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1040 mp->speed = param; |
0 | 1041 else |
1042 jmpSetTempo(mp, param); | |
1043 } | |
1044 break; | |
1045 | |
1046 case 'G': // Gxx = Global Volume | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1047 mp->globalVol = param; |
0 | 1048 JMPSETNDFLAGS(cdfNewGlobalVol); |
1049 break; | |
1050 | |
1051 | |
1052 case 'H': // Hxx = Global Volume Slide | |
1053 JMPDEBUG("Global Volume Slide used, UNIMPLEMENTED"); | |
1054 break; | |
1055 | |
1056 case 'K': // Kxx = Key-off (Same as key-off note) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1057 chn->iCKeyOff = TRUE; |
0 | 1058 break; |
1059 | |
1060 case 'L': // Lxx = Set Envelope Position | |
1061 JMPDEBUG("Set Envelope Position used, NOT verified with FT2"); | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1062 chn->iCPanEnv_Frames = param; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1063 chn->iCVolEnv_Frames = param; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1064 chn->iCPanEnv_Exec = TRUE; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1065 chn->iCVolEnv_Exec = TRUE; |
0 | 1066 break; |
1067 | |
1068 case 'R': // Rxy = Multi Retrig note | |
1069 JMPDEBUG("Multi Retrig Note used, UNIMPLEMENTED"); | |
1070 break; | |
1071 | |
1072 case 'T': // Txy = Tremor | |
1073 if (param) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1074 chn->iLastTremorParam = param; |
0 | 1075 break; |
1076 | |
1077 case 'X': // Xxy = Extra Fine Portamento | |
1078 switch (paramX) | |
1079 { | |
1080 case 0x01: // X1y - Extra Fine Portamento Up | |
1081 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1082 chn->iCLastExtraFinePortamentoUpParam = paramY; |
0 | 1083 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1084 jmpChangePitch(chn, channel, - chn->iCLastExtraFinePortamentoUpParam); |
0 | 1085 break; |
1086 | |
1087 case 0x02: // X2y - Extra Fine Portamento Down | |
1088 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1089 chn->iCLastExtraFinePortamentoDownParam = paramY; |
0 | 1090 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1091 jmpChangePitch(chn, channel, chn->iCLastExtraFinePortamentoUpParam); |
0 | 1092 break; |
1093 | |
1094 default: | |
1095 JMPDEBUG("Unsupported value in Extra Fine Portamento command!"); | |
1096 break; | |
1097 } | |
1098 break; | |
1099 | |
1100 default: | |
1101 JMPDEBUG("Unsupported effect"); | |
1102 break; | |
1103 } | |
1104 } | |
1105 | |
1106 | |
1107 static void jmpProcessNewRow(JSSPlayer * mp, int channel) | |
1108 { | |
1109 JSSNote *currNote; | |
1110 JSSExtInstrument *extInst = NULL; | |
1111 JSSInstrument *inst = NULL; | |
1112 BOOL newNote = FALSE; | |
1113 int tmp, paramX, paramY; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1114 JSSPlayerChannel *chn = &(mp->channels[channel]); |
0 | 1115 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1116 JMPGETNOTE(currNote, mp->row, channel); |
0 | 1117 |
1118 // Check for a new note/keyoff here | |
1119 if (currNote->note == jsetNoteOff) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1120 chn->iCKeyOff = TRUE; |
0 | 1121 else |
1122 if (currNote->note >= 0 && currNote->note <= 96) | |
1123 { | |
1124 // New note was set | |
1125 newNote = TRUE; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1126 chn->iCNote = currNote->note; |
0 | 1127 } |
1128 | |
1129 // Check for new instrument | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1130 if (currNote->instrument != jsetNotSet) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1131 { |
0 | 1132 /* Envelopes and ext.instrument fadeout are initialized always if |
1133 * new instrument is set, even if the instrument does not exist. | |
1134 */ | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1135 jmpResetEnvelopes(chn); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1136 chn->iCKeyOff = FALSE; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1137 chn->iCFadeOutVol = mpMaxFadeoutVol; |
0 | 1138 |
1139 // We save the instrument number here for later use | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1140 if (currNote->instrument >= 0 && currNote->instrument < mp->module->nextInstruments) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1141 chn->iCExtInstrumentN = currNote->instrument; |
0 | 1142 } |
1143 | |
1144 /* ONLY if newNote was SET NOW and ExtInstrument HAS BEEN set, we can | |
1145 * set new pitches, and other things... | |
1146 */ | |
1147 if (newNote) | |
1148 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1149 if (chn->iCExtInstrumentN != jsetNotSet) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1150 extInst = mp->module->extInstruments[chn->iCExtInstrumentN]; |
0 | 1151 else |
1152 extInst = NULL; | |
1153 | |
1154 if (extInst) | |
1155 { | |
1156 // Set instrument | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1157 int note = chn->iCNote; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1158 chn->iCExtInstrument = extInst; |
0 | 1159 |
1160 // We set new Instrument ONLY if NEW NOTE has been set | |
1161 if (note != jsetNotSet) | |
1162 { | |
1163 // Get instrument number | |
1164 tmp = extInst->sNumForNotes[note]; | |
1165 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1166 if (tmp >= 0 && tmp < mp->module->ninstruments) { |
0 | 1167 // Set the new instrument |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1168 inst = mp->module->instruments[tmp]; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1169 chn->iCInstrumentN = tmp; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1170 chn->iCInstrument = inst; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1171 chn->iCVolume = inst->volume; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1172 chn->iCPanning = inst->EPanning; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1173 chn->iCPosition = 0; |
0 | 1174 |
1175 // Set NDFlags | |
1176 JMPSETNDFLAGS(cdfNewInstr | cdfNewPos | cdfNewPanPos | cdfNewVolume); | |
1177 } | |
1178 } | |
1179 } | |
1180 } | |
1181 | |
1182 if (inst) | |
1183 { | |
1184 // Save old pitch for later use | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1185 chn->iCOldPitch = chn->iCPitch; |
0 | 1186 |
1187 // Compute new pitch | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1188 tmp = (chn->iCNote + inst->ERelNote); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1189 //fprintf(stderr, "HEH: %d + %d = %d\n", chn->iCNote, inst->ERelNote, tmp); |
0 | 1190 if (tmp < 0) |
1191 tmp = 0; | |
1192 else if (tmp > 119) | |
1193 tmp = 119; | |
1194 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1195 chn->iCPitch = jmpGetPeriodFromNote(mp, tmp, inst->EFineTune); |
0 | 1196 JMPSETNDFLAGS(cdfNewPitch); |
1197 } | |
1198 | |
1199 // Process the volume column | |
1200 JMPMAKEPARAM(currNote->volume, paramX, paramY); | |
1201 | |
1202 switch (paramX) | |
1203 { | |
1204 case 0x00: | |
1205 case 0x01: | |
1206 case 0x02: | |
1207 case 0x03: | |
1208 case 0x04: | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1209 jmpSetVolume(chn, channel, currNote->volume); |
0 | 1210 break; |
1211 | |
1212 case 0x07: // Dx = Fine Volumeslide Down : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1213 jmpChangeVolume(chn, channel, -paramY); |
0 | 1214 break; |
1215 | |
1216 case 0x08: // Ux = Fine Volumeslide Up : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1217 jmpChangeVolume(chn, channel, paramY); |
0 | 1218 break; |
1219 | |
1220 case 0x09: // Sx = Set vibrato speed : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1221 chn->iVibratoSpeed = paramY; |
0 | 1222 break; |
1223 | |
1224 case 0x0a: // Vx = Vibrato : IMPL.VERIFIED | |
1225 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1226 chn->iVibratoDepth = paramY; |
0 | 1227 break; |
1228 | |
1229 case 0x0e: // Mx = Porta To Note : IMPL.VERIFIED | |
1230 if (paramY) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1231 chn->iLastPortaToNoteParam = paramY; |
0 | 1232 |
1233 if (currNote->note != jsetNotSet && currNote->note != jsetNoteOff) { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1234 chn->iLastPortaToNotePitch = chn->iCPitch; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1235 chn->iCPitch = chn->iCOldPitch; |
0 | 1236 JMPUNSETNDFLAGS(cdfNewPitch | cdfNewInstr | cdfNewPanPos); |
1237 } | |
1238 break; | |
1239 } | |
1240 | |
1241 // ...And finally process the Normal effects | |
1242 if (currNote->effect != jsetNotSet) | |
1243 jmpProcessRowEffect(mp, channel, currNote); | |
1244 } | |
1245 | |
1246 | |
1247 static void jmpProcessEffects(JSSPlayer * mp, int channel) | |
1248 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1249 JSSPlayerChannel *chn = &(mp->channels[channel]); |
0 | 1250 JSSNote *currNote; |
1251 int param, paramX, paramY, tmp; | |
1252 char effect; | |
1253 | |
1254 // Process the volume column effects | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1255 JMPGETNOTE(currNote, mp->row, channel); |
0 | 1256 JMPMAKEPARAM(currNote->volume, paramX, paramY); |
1257 | |
1258 switch (paramX) | |
1259 { | |
1260 case 0x05: // -x = Volumeslide Down : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1261 jmpChangeVolume(chn, channel, -paramY); |
0 | 1262 break; |
1263 | |
1264 case 0x06: // +x = Volumeslide Down : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1265 jmpChangeVolume(chn, channel, paramY); |
0 | 1266 break; |
1267 | |
1268 case 0x0a: // Vx = Vibrato : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1269 jmpDoVibrato(mp, chn, channel); |
0 | 1270 break; |
1271 | |
1272 case 0x0e: // Mx = Porta To Note : IMPL.VERIFIED | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1273 jmpDoPortamento(chn, channel); |
0 | 1274 break; |
1275 } | |
1276 | |
1277 // ...And finally process the Normal effects | |
1278 if (currNote->effect == jsetNotSet) | |
1279 return; | |
1280 | |
1281 param = currNote->param; | |
1282 JMPMAKEPARAM(param, paramX, paramY); | |
1283 JMPGETEFFECT(effect, currNote->effect); | |
1284 | |
1285 switch (effect) | |
1286 { | |
1287 case '0': // 0xy = Arpeggio | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1288 jmpDoArpeggio(mp, chn, channel, paramX, paramY); |
0 | 1289 break; |
1290 | |
1291 case '1': // 1xy = Portamento Up | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1292 if (chn->iLastPortaParam > 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1293 jmpChangePitch(chn, channel, -(chn->iLastPortaParam * 4)); |
0 | 1294 break; |
1295 | |
1296 case '2': // 2xy = Portamento Down | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1297 if (chn->iLastPortaParam > 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1298 jmpChangePitch(chn, channel, (chn->iLastPortaParam * 4)); |
0 | 1299 break; |
1300 | |
1301 case '3': // 3xy = Porta To Note | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1302 jmpDoPortamento(chn, channel); |
0 | 1303 break; |
1304 | |
1305 case '4': // 4xy = Vibrato | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1306 jmpDoVibrato(mp, chn, channel); |
0 | 1307 break; |
1308 | |
1309 case '5': // 5xy = Portamento + Volume Slide | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1310 jmpDoPortamento(chn, channel); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1311 jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); |
0 | 1312 break; |
1313 | |
1314 case '6': // 6xy = Vibrato + Volume Slide | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1315 jmpDoVibrato(mp, chn, channel); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1316 jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); |
0 | 1317 break; |
1318 | |
1319 case '7': // 7xy = Tremolo | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1320 jmpDoTremolo(mp, chn, channel); |
0 | 1321 break; |
1322 | |
1323 case 'A': // Axy = Volume slide | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1324 jmpDoVolumeSlide(chn, channel, chn->iLastVolSlideParam); |
0 | 1325 break; |
1326 | |
1327 case 'E': // Exy = Special Effects | |
1328 switch (paramX) | |
1329 { | |
1330 case 0x0c: // ECx - Set Note Cut | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1331 if (mp->tick == paramY) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1332 jmpSetVolume(chn, channel, jsetMinVol); |
0 | 1333 break; |
1334 | |
1335 case 0x0d: // EDx - Set Note Delay | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1336 if (mp->tick == paramY) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1337 chn->iCNewDataFlags = chn->iSaveNDFlags; |
0 | 1338 break; |
1339 } | |
1340 break; | |
1341 | |
1342 case 'T': // Txy = Tremor | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1343 JMPMAKEPARAM(chn->iLastTremorParam, paramX, paramY) |
0 | 1344 paramX++; |
1345 paramY++; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1346 tmp = (chn->iTremorCount % (paramX + paramY)); |
0 | 1347 if (tmp < paramX) |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1348 jmpCSetVolume(mp, chn, channel, chn->iCVolume); |
0 | 1349 else |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1350 jmpCSetVolume(mp, chn, channel, jsetMinVol); |
0 | 1351 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1352 chn->iTremorCount = (tmp + 1); |
0 | 1353 break; |
1354 } | |
1355 } | |
1356 | |
1357 | |
1358 /* This is the main processing callback-loop of a module player. | |
1359 * It processes the ticks, calling the needed jmpProcessNewRow() | |
1360 * and jmpProcessEffects() methods for processing the module playing. | |
1361 */ | |
1362 void jmpExec(void *pDEV, void *pMP) | |
1363 { | |
1364 JSSPlayer *mp; | |
1365 JSSMixer *dev; | |
1366 int channel, flags; | |
1367 | |
1368 // Check some things via assert() | |
1369 assert(pMP != NULL); | |
1370 mp = (JSSPlayer *) pMP; | |
1371 JSS_LOCK(mp); | |
1372 | |
1373 dev = (JSSMixer *) pDEV; | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1374 assert(mp->device == dev); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1375 assert(mp->module != NULL); |
0 | 1376 |
1377 // Check if we are playing | |
1378 if (!mp->isPlaying) | |
1379 goto out; | |
1380 | |
1381 // Clear channel new data flags | |
1382 mp->jumpFlag = FALSE; | |
1383 mp->breakFlag = FALSE; | |
1384 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1385 for (channel = 0; channel < jsetNChannels; channel++) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1386 mp->channels[channel].iCNewDataFlags = 0; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1387 |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1388 //fprintf(stderr, "1: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); |
0 | 1389 |
1390 // Check for init-tick | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1391 if (mp->tick < 0) |
0 | 1392 { |
1393 // Initialize pattern | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1394 if (mp->order != jsetNotSet) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1395 jmpSetNewOrder(mp, mp->order); |
0 | 1396 |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1397 mp->newRow = 0; |
0 | 1398 mp->newRowSet = TRUE; |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1399 mp->tick = mp->speed; |
0 | 1400 } |
1401 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1402 //fprintf(stderr, "2: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); |
0 | 1403 |
1404 // Check if we are playing | |
1405 if (!mp->isPlaying) | |
1406 goto out; | |
1407 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1408 assert(mp->pattern); |
0 | 1409 |
1410 // Update the tick | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1411 mp->tick++; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1412 if (mp->tick >= mp->speed) |
0 | 1413 { |
1414 // Re-init tick counter | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1415 mp->tick = 0; |
0 | 1416 |
1417 // Check pattern delay | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1418 if (mp->patternDelay > 0) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1419 mp->patternDelay--; |
0 | 1420 else |
1421 { | |
1422 // New pattern row | |
1423 if (mp->newRowSet) | |
1424 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1425 mp->row = mp->newRow; |
0 | 1426 mp->newRowSet = FALSE; |
1427 } else | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1428 mp->row++; |
0 | 1429 |
1430 // Check for end of pattern | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1431 if (mp->row >= mp->pattern->nrows) |
0 | 1432 { |
1433 // Go to next order | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1434 if (mp->order != jsetNotSet) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1435 jmpSetNewOrder(mp, mp->order + 1); |
0 | 1436 else |
1437 mp->isPlaying = FALSE; | |
1438 | |
1439 // Check for FT2 quirks | |
1440 if (JMPGETMODFLAGS(mp, jmdfFT2Replay)) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1441 mp->row = mp->lastPatLoopRow; |
0 | 1442 else |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1443 mp->row = 0; |
0 | 1444 } |
1445 | |
1446 if (!mp->isPlaying) | |
1447 goto out; | |
1448 | |
1449 // Check current order | |
1450 if (mp->newOrderSet) | |
1451 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1452 jmpSetNewOrder(mp, mp->newOrder); |
0 | 1453 mp->newOrderSet = FALSE; |
1454 } | |
1455 | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1456 //fprintf(stderr, "3: tick=%d, order=%d, iPattern=%d, row=%d\n", mp->tick, mp->order, mp->npattern, mp->row); |
0 | 1457 |
1458 if (!mp->isPlaying) | |
1459 goto out; | |
1460 | |
1461 // TICK #0: Process new row | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1462 for (channel = 0; channel < mp->module->nchannels; channel++) |
0 | 1463 jmpProcessNewRow(mp, channel); |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1464 } // patternDelay |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1465 } // tick |
0 | 1466 else |
1467 { | |
1468 // Implement FT2's pattern delay-effect: don't update effects while on patdelay | |
1469 if (!JMPGETMODFLAGS(mp, jmdfFT2Replay) || | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1470 (JMPGETMODFLAGS(mp, jmdfFT2Replay) && mp->patternDelay <= 0)) |
0 | 1471 { |
1472 // TICK n: Process the effects | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1473 for (channel = 0; channel < mp->module->nchannels; channel++) |
0 | 1474 jmpProcessEffects(mp, channel); |
1475 } | |
1476 } | |
1477 | |
1478 // Check if playing has stopped | |
1479 if (!mp->isPlaying) | |
1480 goto out; | |
1481 | |
1482 // Update player data to audio device/mixer | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1483 for (channel = 0; channel < mp->module->nchannels; channel++) |
0 | 1484 { |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1485 JSSPlayerChannel *chn = &mp->channels[channel]; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1486 |
0 | 1487 // Process extended instruments |
61
a33e47232161
Silence some "unused parameter" warnings.
Matti Hamalainen <ccr@tnsp.org>
parents:
55
diff
changeset
|
1488 jmpProcessExtInstrument(chn, channel); |
0 | 1489 |
1490 // Check NDFlags and update channel data | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1491 flags = chn->iCNewDataFlags; |
0 | 1492 if (flags) |
1493 { | |
1494 // Check if we stop? | |
1495 if (flags & cdfStop) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1496 { |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1497 jvmStop(mp->device, channel); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1498 } |
0 | 1499 else |
1500 { | |
1501 // No, handle other flags | |
1502 if (flags & cdfNewInstr) | |
1503 { | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1504 JSSInstrument *instr = chn->iCInstrument; |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1505 if (instr != NULL) |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1506 { |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1507 jvmSetSample(mp->device, channel, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1508 instr->data, instr->size, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1509 instr->loopS, instr->loopE, |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1510 instr->flags); |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1511 } |
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1512 jvmPlay(mp->device, channel); |
0 | 1513 } |
1514 | |
1515 if (flags & cdfNewPitch) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1516 jmpCSetPitch(mp, channel, chn->iCPitch); |
0 | 1517 |
1518 if (flags & cdfNewPos) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1519 jmpCSetPosition(mp, channel, chn->iCPosition); |
0 | 1520 |
1521 if (flags & cdfNewVolume) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1522 jmpCSetVolume(mp, chn, channel, chn->iCVolume); |
0 | 1523 |
1524 if (flags & cdfNewPanPos) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1525 jmpCSetPanning(mp, chn, channel, chn->iCPanning); |
0 | 1526 |
1527 if (flags & cdfNewGlobalVol) | |
55
e0e470c3fc8e
Initial round of cleaning up the player code a bit.
Matti Hamalainen <ccr@tnsp.org>
parents:
30
diff
changeset
|
1528 jvmSetGlobalVol(mp->device, mp->globalVol); |
0 | 1529 } |
1530 } | |
1531 } | |
1532 | |
1533 out: | |
1534 JSS_UNLOCK(mp); | |
1535 } |