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