1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "scumm/players/player_v2base.h"
24 #include "scumm/scumm.h"
25
26 #define FREQ_HZ 236 // Don't change!
27
28 #define MAX_OUTPUT 0x7fff
29
30 namespace Scumm {
31
32 const uint8 note_lengths[] = {
33 0,
34 0, 0, 2,
35 0, 3, 4,
36 5, 6, 8,
37 9, 12, 16,
38 18, 24, 32,
39 36, 48, 64,
40 72, 96
41 };
42
43 static const uint16 hull_offsets[] = {
44 0, 12, 24, 36, 48, 60,
45 72, 88, 104, 120, 136, 256,
46 152, 164, 180
47 };
48
49 static const int16 hulls[] = {
50 // hull 0
51 3, -1, 0, 0, 0, 0, 0, 0,
52 0, -1, 0, 0,
53 // hull 1 (staccato)
54 3, -1, 0, 32, 0, -1, 0, 0,
55 0, -1, 0, 0,
56 // hull 2 (legato)
57 3, -1, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0,
59 // hull 3 (staccatissimo)
60 3, -1, 0, 2, 0, -1, 0, 0,
61 0, -1, 0, 0,
62 // hull 4
63 3, -1, 0, 6, 0, -1, 0, 0,
64 0, -1, 0, 0,
65 // hull 5
66 3, -1, 0, 16, 0, -1, 0, 0,
67 0, -1, 0, 0,
68 // hull 6
69 (int16) 60000, -1, -1000, 20, 0, 0, 0, 0,
70 (int16) 40000, -1, -5000, 5, 0, -1, 0, 0,
71 // hull 7
72 (int16) 50000, -1, 0, 8, 30000, -1, 0, 0,
73 28000, -1, -5000, 5, 0, -1, 0, 0,
74 // hull 8
75 (int16) 60000, -1, -2000, 16, 0, 0, 0, 0,
76 28000, -1, -6000, 5, 0, -1, 0, 0,
77 // hull 9
78 (int16) 55000, -1, 0, 8, (int16) 35000, -1, 0, 0,
79 (int16) 40000, -1, -2000, 10, 0, -1, 0, 0,
80 // hull 10
81 (int16) 60000, -1, 0, 4, -2000, 8, 0, 0,
82 (int16) 40000, -1, -6000, 5, 0, -1, 0, 0,
83 // hull 12
84 0, -1, 150, 340, -150, 340, 0, -1,
85 0, -1, 0, 0,
86 // hull 13 == 164
87 20000, -1, 4000, 7, 1000, 15, 0, 0,
88 (int16) 35000, -1, -2000, 15, 0, -1, 0, 0,
89
90 // hull 14 == 180
91 (int16) 35000, -1, 500, 20, 0, 0, 0, 0,
92 (int16) 45000, -1, -500, 60, 0, -1, 0, 0,
93
94 // hull misc = 196
95 (int16) 44000, -1, -4400, 10, 0, -1, 0, 0,
96 0, -1, 0, 0,
97
98 (int16) 53000, -1, -5300, 10, 0, -1, 0, 0,
99 0, -1, 0, 0,
100
101 (int16) 63000, -1, -6300, 10, 0, -1, 0, 0,
102 0, -1, 0, 0,
103
104 (int16) 44000, -1, -1375, 32, 0, -1, 0, 0,
105 0, -1, 0, 0,
106
107 (int16) 53000, -1, -1656, 32, 0, -1, 0, 0,
108 0, -1, 0, 0,
109
110 // hull 11 == 256
111 (int16) 63000, -1, -1968, 32, 0, -1, 0, 0,
112 0, -1, 0, 0,
113
114 (int16) 44000, -1, - 733, 60, 0, -1, 0, 0,
115 0, -1, 0, 0,
116
117 (int16) 53000, -1, - 883, 60, 0, -1, 0, 0,
118 0, -1, 0, 0,
119
120 (int16) 63000, -1, -1050, 60, 0, -1, 0, 0,
121 0, -1, 0, 0,
122
123 (int16) 44000, -1, - 488, 90, 0, -1, 0, 0,
124 0, -1, 0, 0,
125
126 (int16) 53000, -1, - 588, 90, 0, -1, 0, 0,
127 0, -1, 0, 0,
128
129 (int16) 63000, -1, - 700, 90, 0, -1, 0, 0,
130 0, -1, 0, 0
131 };
132
133 static const uint16 freqmod_lengths[] = {
134 0x1000, 0x1000, 0x20, 0x2000, 0x1000
135 };
136
137 static const uint16 freqmod_offsets[] = {
138 0, 0x100, 0x200, 0x302, 0x202
139 };
140
141 static const int8 freqmod_table[0x502] = {
142 0, 3, 6, 9, 12, 15, 18, 21,
143 24, 27, 30, 33, 36, 39, 42, 45,
144 48, 51, 54, 57, 59, 62, 65, 67,
145 70, 73, 75, 78, 80, 82, 85, 87,
146 89, 91, 94, 96, 98, 100, 102, 103,
147 105, 107, 108, 110, 112, 113, 114, 116,
148 117, 118, 119, 120, 121, 122, 123, 123,
149 124, 125, 125, 126, 126, 126, 126, 126,
150 126, 126, 126, 126, 126, 126, 125, 125,
151 124, 123, 123, 122, 121, 120, 119, 118,
152 117, 116, 114, 113, 112, 110, 108, 107,
153 105, 103, 102, 100, 98, 96, 94, 91,
154 89, 87, 85, 82, 80, 78, 75, 73,
155 70, 67, 65, 62, 59, 57, 54, 51,
156 48, 45, 42, 39, 36, 33, 30, 27,
157 24, 21, 18, 15, 12, 9, 6, 3,
158 0, -3, -6, -9, -12, -15, -18, -21,
159 -24, -27, -30, -33, -36, -39, -42, -45,
160 -48, -51, -54, -57, -59, -62, -65, -67,
161 -70, -73, -75, -78, -80, -82, -85, -87,
162 -89, -91, -94, -96, -98,-100,-102,-103,
163 -105,-107,-108,-110,-112,-113,-114,-116,
164 -117,-118,-119,-120,-121,-122,-123,-123,
165 -124,-125,-125,-126,-126,-126,-126,-126,
166 -126,-126,-126,-126,-126,-126,-125,-125,
167 -124,-123,-123,-122,-121,-120,-119,-118,
168 -117,-116,-114,-113,-112,-110,-108,-107,
169 -105,-103,-102,-100, -98, -96, -94, -91,
170 -89, -87, -85, -82, -80, -78, -75, -73,
171 -70, -67, -65, -62, -59, -57, -54, -51,
172 -48, -45, -42, -39, -36, -33, -30, -27,
173 -24, -21, -18, -15, -12, -9, -6, -3,
174
175 0, 1, 2, 3, 4, 5, 6, 7,
176 8, 9, 10, 11, 12, 13, 14, 15,
177 16, 17, 18, 19, 20, 21, 22, 23,
178 24, 25, 26, 27, 28, 29, 30, 31,
179 32, 33, 34, 35, 36, 37, 38, 39,
180 40, 41, 42, 43, 44, 45, 46, 47,
181 48, 49, 50, 51, 52, 53, 54, 55,
182 56, 57, 58, 59, 60, 61, 62, 63,
183 64, 65, 66, 67, 68, 69, 70, 71,
184 72, 73, 74, 75, 76, 77, 78, 79,
185 80, 81, 82, 83, 84, 85, 86, 87,
186 88, 89, 90, 91, 92, 93, 94, 95,
187 96, 97, 98, 99, 100, 101, 102, 103,
188 104, 105, 106, 107, 108, 109, 110, 111,
189 112, 113, 114, 115, 116, 117, 118, 119,
190 120, 121, 122, 123, 124, 125, 126, 127,
191 -128,-127,-126,-125,-124,-123,-122,-121,
192 -120,-119,-118,-117,-116,-115,-114,-113,
193 -112,-111,-110,-109,-108,-107,-106,-105,
194 -104,-103,-102,-101,-100, -99, -98, -97,
195 -96, -95, -94, -93, -92, -91, -90, -89,
196 -88, -87, -86, -85, -84, -83, -82, -81,
197 -80, -79, -78, -77, -76, -75, -74, -73,
198 -72, -71, -70, -69, -68, -67, -66, -65,
199 -64, -63, -62, -61, -60, -59, -58, -57,
200 -56, -55, -54, -53, -52, -51, -50, -49,
201 -48, -47, -46, -45, -44, -43, -42, -41,
202 -40, -39, -38, -37, -36, -35, -34, -33,
203 -32, -31, -30, -29, -28, -27, -26, -25,
204 -24, -23, -22, -21, -20, -19, -18, -17,
205 -16, -15, -14, -13, -12, -11, -10, -9,
206 -8, -7, -6, -5, -4, -3, -2, -1,
207
208 -120, 120,
209
210 -120,-120,-120,-120,-120,-120,-120,-120,
211 -120,-120,-120,-120,-120,-120,-120,-120,
212 -120,-120,-120,-120,-120,-120,-120,-120,
213 -120,-120,-120,-120,-120,-120,-120,-120,
214 -120,-120,-120,-120,-120,-120,-120,-120,
215 -120,-120,-120,-120,-120,-120,-120,-120,
216 -120,-120,-120,-120,-120,-120,-120,-120,
217 -120,-120,-120,-120,-120,-120,-120,-120,
218 -120,-120,-120,-120,-120,-120,-120,-120,
219 -120,-120,-120,-120,-120,-120,-120,-120,
220 -120,-120,-120,-120,-120,-120,-120,-120,
221 -120,-120,-120,-120,-120,-120,-120,-120,
222 -120,-120,-120,-120,-120,-120,-120,-120,
223 -120,-120,-120,-120,-120,-120,-120,-120,
224 -120,-120,-120,-120,-120,-120,-120,-120,
225 -120,-120,-120,-120,-120,-120,-120,-120,
226 120, 120, 120, 120, 120, 120, 120, 120,
227 120, 120, 120, 120, 120, 120, 120, 120,
228 120, 120, 120, 120, 120, 120, 120, 120,
229 120, 120, 120, 120, 120, 120, 120, 120,
230 120, 120, 120, 120, 120, 120, 120, 120,
231 120, 120, 120, 120, 120, 120, 120, 120,
232 120, 120, 120, 120, 120, 120, 120, 120,
233 120, 120, 120, 120, 120, 120, 120, 120,
234 120, 120, 120, 120, 120, 120, 120, 120,
235 120, 120, 120, 120, 120, 120, 120, 120,
236 120, 120, 120, 120, 120, 120, 120, 120,
237 120, 120, 120, 120, 120, 120, 120, 120,
238 120, 120, 120, 120, 120, 120, 120, 120,
239 120, 120, 120, 120, 120, 120, 120, 120,
240 120, 120, 120, 120, 120, 120, 120, 120,
241 120, 120, 120, 120, 120, 120, 120, 120,
242
243 41, 35, -66,-124, -31, 108, -42, -82,
244 82,-112, 73, -15, -15, -69, -23, -21,
245 -77, -90, -37, 60,-121, 12, 62,-103,
246 36, 94, 13, 28, 6, -73, 71, -34,
247 -77, 18, 77, -56, 67, -69,-117, -90,
248 31, 3, 90, 125, 9, 56, 37, 31,
249 93, -44, -53, -4,-106, -11, 69, 59,
250 19, 13,-119, 10, 28, -37, -82, 50,
251 32,-102, 80, -18, 64, 120, 54, -3,
252 18, 73, 50, -10, -98, 125, 73, -36,
253 -83, 79, 20, -14, 68, 64, 102, -48,
254 107, -60, 48, -73, 50, 59, -95, 34,
255 -10, 34,-111, -99, -31,-117, 31, -38,
256 -80, -54,-103, 2, -71, 114, -99, 73,
257 44,-128, 126, -59,-103, -43, -23,-128,
258 -78, -22, -55, -52, 83, -65, 103, -42,
259 -65, 20, -42, 126, 45, -36,-114, 102,
260 -125, -17, 87, 73, 97, -1, 105,-113,
261 97, -51, -47, 30, -99,-100, 22, 114,
262 114, -26, 29, -16,-124, 79, 74, 119,
263 2, -41, -24, 57, 44, 83, -53, -55,
264 18, 30, 51, 116, -98, 12, -12, -43,
265 -44, -97, -44, -92, 89, 126, 53, -49,
266 50, 34, -12, -52, -49, -45,-112, 45,
267 72, -45,-113, 117, -26, -39, 29, 42,
268 -27, -64, -9, 43, 120,-127,-121, 68,
269 14, 95, 80, 0, -44, 97,-115, -66,
270 123, 5, 21, 7, 59, 51,-126, 31,
271 24, 112,-110, -38, 100, 84, -50, -79,
272 -123, 62, 105, 21, -8, 70, 106, 4,
273 -106, 115, 14, -39, 22, 47, 103, 104,
274 -44, -9, 74, 74, -48, 87, 104, 118,
275 -6, 22, -69, 17, -83, -82, 36,-120,
276 121, -2, 82, -37, 37, 67, -27, 60,
277 -12, 69, -45, -40, 40, -50, 11, -11,
278 -59, 96, 89, 61,-105, 39,-118, 89,
279 118, 45, -48, -62, -55, -51, 104, -44,
280 73, 106, 121, 37, 8, 97, 64, 20,
281 -79, 59, 106, -91, 17, 40, -63,-116,
282 -42, -87, 11,-121,-105,-116, 47, -15,
283 21, 29,-102,-107, -63,-101, -31, -64,
284 126, -23, -88,-102, -89,-122, -62, -75,
285 84, -65,-102, -25, -39, 35, -47, 85,
286 -112, 56, 40, -47, -39, 108, -95, 102,
287 94, 78, -31, 48,-100, -2, -39, 113,
288 -97, -30, -91, -30, 12,-101, -76, 71,
289 101, 56, 42, 70,-119, -87,-126, 121,
290 122, 118, 120, -62, 99, -79, 38, -33,
291 -38, 41, 109, 62, 98, -32,-106, 18,
292 52, -65, 57, -90, 63,-119, 94, -15,
293 109, 14, -29, 108, 40, -95, 30, 32,
294 29, -53, -62, 3, 63, 65, 7,-124,
295 15, 20, 5, 101, 27, 40, 97, -55,
296 -59, -25, 44,-114, 70, 54, 8, -36,
297 -13, -88,-115, -2, -66, -14, -21, 113,
298 -1, -96, -48, 59, 117, 6,-116, 126,
299 -121, 120, 115, 77, -48, -66,-126, -66,
300 -37, -62, 70, 65, 43,-116, -6, 48,
301 127, 112, -16, -89, 84,-122, 50,-107,
302 -86, 91, 104, 19, 11, -26, -4, -11,
303 -54, -66, 125, -97,-119,-118, 65, 27,
304 -3, -72, 79, 104, -10, 114, 123, 20,
305 -103, -51, -45, 13, -16, 68, 58, -76,
306 -90, 102, 83, 51, 11, -53, -95, 16
307 };
308
309 static const uint16 spk_freq_table[12] = {
310 36484, 34436, 32503, 30679, 28957, 27332,
311 25798, 24350, 22983, 21693, 20476, 19326
312 };
313
314 static const uint16 pcjr_freq_table[12] = {
315 65472, 61760, 58304, 55040, 52032, 49024,
316 46272, 43648, 41216, 38912, 36736, 34624
317 };
318
319
Player_V2Base(ScummEngine * scumm,Audio::Mixer * mixer,bool pcjr)320 Player_V2Base::Player_V2Base(ScummEngine *scumm, Audio::Mixer *mixer, bool pcjr)
321 : _vm(scumm),
322 _mixer(mixer),
323 _pcjr(pcjr),
324 _sampleRate(_mixer->getOutputRate()) {
325
326 _isV3Game = (scumm->_game.version >= 3);
327
328 _header_len = (scumm->_game.features & GF_OLD_BUNDLE) ? 4 : 6;
329
330 // Initialize sound queue
331 _current_nr = _next_nr = 0;
332 _current_data = _next_data = 0;
333
334 _retaddr = 0;
335
336 // Initialize channel code
337 for (int i = 0; i < 4; ++i)
338 clear_channel(i);
339
340 _next_tick = 0;
341 _tick_len = (_sampleRate << FIXP_SHIFT) / FREQ_HZ;
342
343 // Initialize V3 music timer
344 _music_timer_ctr = _music_timer = 0;
345 _ticks_per_music_timer = 65535;
346
347 if (_pcjr) {
348 _freqs_table = pcjr_freq_table;
349 } else {
350 _freqs_table = spk_freq_table;
351 }
352 }
353
~Player_V2Base()354 Player_V2Base::~Player_V2Base() {
355 }
356
chainSound(int nr,byte * data)357 void Player_V2Base::chainSound(int nr, byte *data) {
358 int offset = _header_len + (_pcjr ? 10 : 2);
359
360 _current_nr = nr;
361 _current_data = data;
362
363 for (int i = 0; i < 4; i++) {
364 clear_channel(i);
365
366 _channels[i].d.music_script_nr = nr;
367 if (data) {
368 _channels[i].d.next_cmd = READ_LE_UINT16(data + offset + 2 * i);
369 if (_channels[i].d.next_cmd) {
370 _channels[i].d.time_left = 1;
371 }
372 }
373 }
374 _music_timer = 0;
375 }
376
chainNextSound()377 void Player_V2Base::chainNextSound() {
378 if (_next_nr) {
379 chainSound(_next_nr, _next_data);
380 _next_nr = 0;
381 _next_data = 0;
382 }
383 }
384
385 // TODO: Merge stopAllSounds, stopSound() and startSound(), using some overriding
386 // perhaps? Player_V2CMS's implementations start like that of Player_V2
387 // but then add some MIDI related stuff.
388
clear_channel(int i)389 void Player_V2Base::clear_channel(int i) {
390 ChannelInfo *channel = &_channels[i];
391 memset(channel, 0, sizeof(ChannelInfo));
392 }
393
getMusicTimer()394 int Player_V2Base::getMusicTimer() {
395 if (_isV3Game)
396 return _music_timer;
397 else
398 return _channels[0].d.music_timer;
399 }
400
execute_cmd(ChannelInfo * channel)401 void Player_V2Base::execute_cmd(ChannelInfo *channel) {
402 uint16 value;
403 int16 offset;
404 uint8 *script_ptr;
405 ChannelInfo * current_channel;
406 ChannelInfo * dest_channel;
407
408 current_channel = channel;
409
410 if (channel->d.next_cmd == 0)
411 goto check_stopped;
412 script_ptr = &_current_data[channel->d.next_cmd];
413
414 for (;;) {
415 uint8 opcode = *script_ptr++;
416 if (opcode >= 0xf8) {
417 switch (opcode) {
418 case 0xf8: // set hull curve
419 debug(7, "channels[%d]: hull curve %2d",
420 (uint)(channel - _channels), *script_ptr);
421 channel->d.hull_curve = hull_offsets[*script_ptr / 2];
422 script_ptr++;
423 break;
424
425 case 0xf9: // set freqmod curve
426 debug(7, "channels[%d]: freqmod curve %2d",
427 (uint)(channel - _channels), *script_ptr);
428 channel->d.freqmod_table = freqmod_offsets[*script_ptr / 4];
429 channel->d.freqmod_modulo = freqmod_lengths[*script_ptr / 4];
430 script_ptr++;
431 break;
432
433 case 0xfd: // clear other channel
434 value = READ_LE_UINT16 (script_ptr) / sizeof (ChannelInfo);
435 debug(7, "clear channel %d", value);
436 script_ptr += 2;
437 // In Indy3, when traveling to Venice a command is
438 // issued to clear channel 4. So we introduce a 4th
439 // channel, which is never used. All OOB accesses are
440 // mapped to this channel.
441 //
442 // The original game had room for 8 channels, but only
443 // channels 0-3 are read, changes to other channels
444 // had no effect.
445 if (value >= ARRAYSIZE (_channels))
446 value = 4;
447 channel = &_channels[value];
448 // fall through
449
450 case 0xfa: // clear current channel
451 if (opcode == 0xfa)
452 debug(7, "clear channel");
453 channel->d.next_cmd = 0;
454 channel->d.base_freq = 0;
455 channel->d.freq_delta = 0;
456 channel->d.freq = 0;
457 channel->d.volume = 0;
458 channel->d.volume_delta = 0;
459 channel->d.inter_note_pause = 0;
460 channel->d.transpose = 0;
461 channel->d.hull_curve = 0;
462 channel->d.hull_offset = 0;
463 channel->d.hull_counter = 0;
464 channel->d.freqmod_table = 0;
465 channel->d.freqmod_offset = 0;
466 channel->d.freqmod_incr = 0;
467 channel->d.freqmod_multiplier = 0;
468 channel->d.freqmod_modulo = 0;
469 break;
470
471 case 0xfb: // ret from subroutine
472 debug(7, "ret from sub");
473 script_ptr = _retaddr;
474 break;
475
476 case 0xfc: // call subroutine
477 offset = READ_LE_UINT16 (script_ptr);
478 debug(7, "subroutine %d", offset);
479 script_ptr += 2;
480 _retaddr = script_ptr;
481 script_ptr = _current_data + offset;
482 break;
483
484 case 0xfe: // loop music
485 opcode = *script_ptr++;
486 offset = READ_LE_UINT16 (script_ptr);
487 script_ptr += 2;
488 debug(7, "loop if %d to %d", opcode, offset);
489 if (!channel->array[opcode / 2] || --channel->array[opcode/2])
490 script_ptr += offset;
491 break;
492
493 case 0xff: // set parameter
494 opcode = *script_ptr++;
495 value = READ_LE_UINT16 (script_ptr);
496 channel->array[opcode / 2] = value;
497 debug(7, "channels[%d]: set param %2d = %5d",
498 (uint)(channel - _channels), opcode, value);
499 script_ptr += 2;
500 if (opcode == 14) {
501 /* tempo var */
502 _ticks_per_music_timer = 125;
503 }
504 if (opcode == 0)
505 goto end;
506 break;
507 }
508 } else { // opcode < 0xf8
509 for (;;) {
510 int16 note, octave;
511 int is_last_note;
512 dest_channel = &_channels[(opcode >> 5) & 3];
513
514 if (!(opcode & 0x80)) {
515
516 int tempo = channel->d.tempo;
517 if (!tempo)
518 tempo = 1;
519 channel->d.time_left = tempo * note_lengths[opcode & 0x1f];
520
521 note = *script_ptr++;
522 is_last_note = note & 0x80;
523 note &= 0x7f;
524 if (note == 0x7f) {
525 debug(8, "channels[%d]: pause %d",
526 (uint)(channel - _channels), channel->d.time_left);
527 goto end;
528 }
529 } else {
530
531 channel->d.time_left = ((opcode & 7) << 8) | *script_ptr++;
532
533 if ((opcode & 0x10)) {
534 debug(8, "channels[%d]: pause %d",
535 (uint)(channel - _channels), channel->d.time_left);
536 goto end;
537 }
538
539 is_last_note = 0;
540 note = (*script_ptr++) & 0x7f;
541 }
542
543 debug(8, "channels[%d]: @%04x note: %3d+%d len: %2d hull: %d mod: %d/%d/%d %s",
544 (uint)(dest_channel - channel), script_ptr ? (uint)(script_ptr - _current_data - 2) : 0,
545 note, (signed short) dest_channel->d.transpose, channel->d.time_left,
546 dest_channel->d.hull_curve, dest_channel->d.freqmod_table,
547 dest_channel->d.freqmod_incr,dest_channel->d.freqmod_multiplier,
548 is_last_note ? "last":"");
549
550 uint16 myfreq;
551 dest_channel->d.time_left = channel->d.time_left;
552 dest_channel->d.note_length =
553 channel->d.time_left - dest_channel->d.inter_note_pause;
554 note += dest_channel->d.transpose;
555 while (note < 0)
556 note += 12;
557 octave = note / 12;
558 note = note % 12;
559 dest_channel->d.hull_offset = 0;
560 dest_channel->d.hull_counter = 1;
561 if (_pcjr && dest_channel == &_channels[3]) {
562 dest_channel->d.hull_curve = 196 + note * 12;
563 myfreq = 384 - 64 * octave;
564 } else {
565 myfreq = _freqs_table[note] >> octave;
566 }
567 dest_channel->d.freq = dest_channel->d.base_freq = myfreq;
568 if (is_last_note)
569 goto end;
570 opcode = *script_ptr++;
571 }
572 }
573 }
574
575 end:
576 channel = current_channel;
577 if (channel->d.time_left) {
578 channel->d.next_cmd = script_ptr - _current_data;
579 return;
580 }
581
582 channel->d.next_cmd = 0;
583
584 check_stopped:
585 int i;
586 for (i = 0; i < 4; i++) {
587 if (_channels[i].d.time_left)
588 return;
589 }
590
591 _current_nr = 0;
592 _current_data = 0;
593 chainNextSound();
594 }
595
next_freqs(ChannelInfo * channel)596 void Player_V2Base::next_freqs(ChannelInfo *channel) {
597 channel->d.volume += channel->d.volume_delta;
598 channel->d.base_freq += channel->d.freq_delta;
599
600 channel->d.freqmod_offset += channel->d.freqmod_incr;
601 if (channel->d.freqmod_offset > channel->d.freqmod_modulo)
602 channel->d.freqmod_offset -= channel->d.freqmod_modulo;
603
604 channel->d.freq =
605 (int)(freqmod_table[channel->d.freqmod_table + (channel->d.freqmod_offset >> 4)])
606 * (int)channel->d.freqmod_multiplier / 256
607 + channel->d.base_freq;
608
609 debug(9, "Freq: %d/%d, %d/%d/%d*%d %d",
610 channel->d.base_freq, (int16)channel->d.freq_delta,
611 channel->d.freqmod_table, channel->d.freqmod_offset,
612 channel->d.freqmod_incr, channel->d.freqmod_multiplier,
613 channel->d.freq);
614
615 if (channel->d.note_length && !--channel->d.note_length) {
616 channel->d.hull_offset = 16;
617 channel->d.hull_counter = 1;
618 }
619
620 if (!--channel->d.time_left) {
621 execute_cmd(channel);
622 }
623
624 if (channel->d.hull_counter && !--channel->d.hull_counter) {
625 for (;;) {
626 const int16 *hull_ptr = hulls
627 + channel->d.hull_curve + channel->d.hull_offset / 2;
628 if (hull_ptr[1] == -1) {
629 channel->d.volume = hull_ptr[0];
630 if (hull_ptr[0] == 0)
631 channel->d.volume_delta = 0;
632 channel->d.hull_offset += 4;
633 } else {
634 channel->d.volume_delta = hull_ptr[0];
635 channel->d.hull_counter = hull_ptr[1];
636 channel->d.hull_offset += 4;
637 break;
638 }
639 }
640 }
641 }
642
nextTick()643 void Player_V2Base::nextTick() {
644 for (int i = 0; i < 4; i++) {
645 if (!_channels[i].d.time_left)
646 continue;
647 next_freqs(&_channels[i]);
648 }
649 if (_music_timer_ctr++ >= _ticks_per_music_timer) {
650 _music_timer_ctr = 0;
651 _music_timer++;
652 }
653 }
654
655
656 } // End of namespace Scumm
657