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