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