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