diff options
Diffstat (limited to 'scumm')
| -rw-r--r-- | scumm/resource.cpp | 608 | ||||
| -rw-r--r-- | scumm/scummvm.cpp | 2 | ||||
| -rw-r--r-- | scumm/sound.cpp | 2 | 
3 files changed, 465 insertions, 147 deletions
diff --git a/scumm/resource.cpp b/scumm/resource.cpp index edc6bc66ab..5b3b67bca3 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -641,8 +641,12 @@ int Scumm::loadResource(int type, int idx) {  	_fileHandle.seek(fileOffs + _fileOffset, SEEK_SET);  	if (_features & GF_OLD_BUNDLE) { -		size = _fileHandle.readUint16LE(); -		_fileHandle.seek(-2, SEEK_CUR); +		if ((_version == 3) && !(_features & GF_AMIGA) && (type == rtSound)) { +			return readSoundResourceSmallHeader(type, idx); +		} else { +			size = _fileHandle.readUint16LE(); +			_fileHandle.seek(-2, SEEK_CUR); +		}  	} else if (_features & GF_SMALL_HEADER) {  		if (!(_features & GF_SMALL_NAMES))  			_fileHandle.seek(8, SEEK_CUR); @@ -895,61 +899,127 @@ static byte ADLIB_INSTR_MIDI_HACK[95] = {  	0x00, 0x00, 0x07, 0x0f, 0x00, 0x00, 0x08, 0x00,   	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0xf7,  	0x04, 0xf0, 0x41, 0x7d, 0x10,  // sysex 16: set instrument -	0x00,                          // part/channel  (offset 28) -	0x01, 0x06, 0x02, 0x0a, 0x08, 0x09, 0x0d, 0x08, 0x04, 0x04, -	0x04, 0x06, 0x02, 0x02, 0x03, 0x07, 0x0f, 0x0d, -	0x05, 0x04, 0x0c, 0x00, 0x03, 0x01, 0x01, 0x00, -	0x00, 0x00, 0x01, 0x01, 0x0e, 0x00, 0x02, 0x02, -	0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x01, -	0x08, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, -	0x06, 0x02, 0x00, 0x00, 0x04, 0x00, 0x03, 0x02, -	0x04, 0x00, 0x00, 0xf7, +	0x00, 0x01,                    // part/channel  (offset 28) +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0xf7,  	0x00, 0xb0, 0x07, 0x64        // Controller 7 = 100 (offset 92)  }; -int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) { +static const byte map_param[7] = { +	0, 2, 3, 4, 8, 9, 0, +}; -	byte * ptr; -	byte ticks, play_once; -	byte music_type, num_instr; -	byte *channel, *instr, *track; -	int i, ch; +static const byte freq2note[128] = { +	/*128*/	6, 6, 6, 6,   +	/*132*/ 7, 7, 7, 7, 7, 7, 7, +	/*139*/ 8, 8, 8, 8, 8, 8, 8, 8, 8, +	/*148*/ 9, 9, 9, 9, 9, 9, 9, 9, 9, +	/*157*/ 10, 10, 10, 10, 10, 10, 10, 10, 10, +	/*166*/ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +	/*176*/ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +	/*186*/ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +	/*197*/ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +	/*209*/ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +	/*222*/ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, +	/*235*/ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, +	/*249*/ 18, 18, 18, 18, 18, 18, 18 +}; +			 +static const uint16 num_steps_table[] = { +	1, 2, 4, 5, +	6, 7, 8, 9, +	10, 12, 14, 16, +	18, 21, 24, 30, +	36, 50, 64, 82, +	100, 136, 160, 192, +	240, 276, 340, 460, +	600, 860, 1200, 1600 +}; +int Scumm::convert_extraflags(byte * ptr, byte * src_ptr) { +	int flags = src_ptr[0]; + +	int t1, t2, t3, t4, time; +	int v1, v2, v3; + +	if (!(flags & 0x80)) +		return -1; + +	t1 = (src_ptr[1] & 0xf0) >> 3; +	t2 = (src_ptr[2] & 0xf0) >> 3; +	t3 = (src_ptr[3] & 0xf0) >> 3 | (flags & 0x40 ? 0x80 : 0); +	t4 = (src_ptr[3] & 0x0f) << 1; +	v1 = (src_ptr[1] & 0x0f); +	v2 = (src_ptr[2] & 0x0f); +	v3 = 31; +	if ((flags & 0x7) == 0) { +	  v1 = v1 + 31 + 8; +	  v2 = v2 + 31 + 8; +	} else { +	  v1 = v1 * 2 + 31; +	  v2 = v2 * 2 + 31; +	} -	src_ptr += 2; -	size -= 2; -	music_type = *(src_ptr);	// 0x80: is music; otherwise not. -	if (music_type != 0x80) { -		// It's an SFX; we don't know how to handle those yet -		debug(4, "Sound %d not played, format not yet supported", idx); -		res.roomoffs[type][idx] = 0xFFFFFFFF; -		return 0; +	/* flags a */ +	if ((flags & 0x7) == 6) +		ptr[0] = 0; +	else { +		ptr[0] = (flags >> 4) & 0xb; +		ptr[1] = map_param[flags & 0x7];  	} -	// The "speed" of the song -	ticks = *(src_ptr + 1); -	 -	// Flag that tells us whether we should loop the song (0) or play it only once (1) -	play_once = *(src_ptr + 2); -	 -	// Number of instruments used -	num_instr = *(src_ptr + 8);	// Normally 8 -	 -	// copy the pointer to instrument data -	channel = src_ptr + 9; -	instr   = src_ptr + 0x11; +	/* extra a */ +	ptr[2] = 0; +	ptr[3] = 0; +	ptr[4] = t1 >> 4; +	ptr[5] = t1 & 0xf; +	ptr[6] = v1 >> 4; +	ptr[7] = v1 & 0xf; +	ptr[8] = t2 >> 4; +	ptr[9] = t2 & 0xf; +	ptr[10] = v2 >> 4; +	ptr[11] = v2 & 0xf; +	ptr[12] = t3 >> 4; +	ptr[13] = t3 & 0xf; +	ptr[14] = t4 >> 4; +	ptr[15] = t4 & 0xf; +	ptr[16] = v3 >> 4; +	ptr[17] = v3 & 0xf; + +	time = num_steps_table[t1] + num_steps_table[t2] +		+ num_steps_table[t3 & 0x7f] + num_steps_table[t4]; +	if (flags & 0x20) { +		int playtime = ((src_ptr[4] >> 4) & 0xf) * 118 +  +			(src_ptr[4] & 0xf) * 8; +		if (playtime > time) +			time = playtime; +	} +	/* +	time = ((src_ptr[4] >> 4) & 0xf) * 118 +  +		(src_ptr[4] & 0xf) * 8; +	*/ +	return time; +} -	// skip over the rest of the header and copy the MIDI data into a buffer -	src_ptr  += 0x11 + 8 * 16; -	size -= 0x11 + 8 * 16; +int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) { -	CHECK_HEAP  -			 -	track = src_ptr; -			 +	byte * ptr; +	byte ticks, play_once; +	byte num_instr; +	byte *channel, *instr, *track; +	byte *tracks[3]; +	int delay, delay2, olddelay; +	int i, ch;  	int total_size = 8 + 16 + 14 + 8 + 7 + 8*sizeof(ADLIB_INSTR_MIDI_HACK) + size;  	total_size += 24;	// Up to 24 additional bytes are needed for the jump sysex  	ptr = createResource(type, idx, total_size); +	byte *start_ptr = ptr;  	memcpy(ptr, "ADL ", 4); ptr += 4;  	uint32 dw = READ_BE_UINT32(&total_size);  	memcpy(ptr, &dw, 4); ptr += 4; @@ -973,125 +1043,373 @@ int Scumm::convertADResource(int type, int idx, byte * src_ptr, int size) {  	dw = READ_BE_UINT32(&total_size);  	memcpy(ptr, &dw, 4); ptr += 4; -	// Conver the ticks into a MIDI tempo.  -	dw = (500000 * 256) / ticks; -	debug(4, "  ticks = %d, speed = %ld", ticks, dw); -	 -	// Write a tempo change SysEx -	memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4; -	*ptr++ = (byte)((dw >> 16) & 0xFF); -	*ptr++ = (byte)((dw >> 8) & 0xFF); -	*ptr++ = (byte)(dw & 0xFF); -		 -	// Copy our hardcoded instrument table into it -	// Then, convert the instrument table as given in this song resource -	// And write it *over* the hardcoded table. -	// Note: we deliberately. - -	/* now fill in the instruments */ -	for (i = 0; i < num_instr; i++) { -		ch = channel[i] - 1; - -		debug(4, "Sound %d: instrument %d on channel %d.",  -			  idx, i, ch); +	src_ptr += 2; +	size -= 2; -	    memcpy(ptr, ADLIB_INSTR_MIDI_HACK,  -			   sizeof(ADLIB_INSTR_MIDI_HACK)); +	if (*src_ptr == 0x80) { +		// 0x80: is music; otherwise not. -		ptr[5]  += ch; -		ptr[28] += ch; -		ptr[92] += ch; -	 -		/* flags_1 */ -		ptr[30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf; -		ptr[30 + 1] = instr[i * 16 + 3] & 0xf; +		// The "speed" of the song +		ticks = *(src_ptr + 1); -		/* oplvl_1 */ -		ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf; -		ptr[30 + 3] = instr[i * 16 + 4] & 0xf; +		// Flag that tells us whether we should loop the song (0) or play it only once (1) +		play_once = *(src_ptr + 2); -		/* atdec_1 */ -		ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf; -		ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf; +		// Number of instruments used +		num_instr = *(src_ptr + 8);	// Normally 8 -		/* sustrel_1 */ -		ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf; -		ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf; +		// copy the pointer to instrument data +		channel = src_ptr + 9; +		instr   = src_ptr + 0x11; -		/* waveform_1 */ -		ptr[30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf; -		ptr[30 + 9] = instr[i * 16 + 7] & 0xf; +		// skip over the rest of the header and copy the MIDI data into a buffer +		src_ptr  += 0x11 + 8 * 16; +		size -= 0x11 + 8 * 16; + +		CHECK_HEAP  +			 +		track = src_ptr; -		/* flags_2 */ -		ptr[30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf; -		ptr[30 + 11] = instr[i * 16 + 8] & 0xf; +		// Conver the ticks into a MIDI tempo.  +		dw = (500000 * 256) / ticks; +		debug(4, "  ticks = %d, speed = %ld", ticks, dw); +			 +		// Write a tempo change SysEx +		memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4; +		*ptr++ = (byte)((dw >> 16) & 0xFF); +		*ptr++ = (byte)((dw >> 8) & 0xFF); +		*ptr++ = (byte)(dw & 0xFF); -		/* oplvl_2 */ -		ptr[30 + 12] = (instr[i * 16 + 9] >> 4) & 0xf; -		ptr[30 + 13] = instr[i * 16 + 9] & 0xf; +		// Copy our hardcoded instrument table into it +		// Then, convert the instrument table as given in this song resource +		// And write it *over* the hardcoded table. +		// Note: we deliberately. -		/* atdec_2 */ -		ptr[30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf; -		ptr[30 + 15] = (~instr[i * 16 + 10]) & 0xf; +		/* now fill in the instruments */ +		for (i = 0; i < num_instr; i++) { +			ch = channel[i] - 1; +			 +			debug(4, "Sound %d: instrument %d on channel %d.",  +				  idx, i, ch); +			 +			memcpy(ptr, ADLIB_INSTR_MIDI_HACK,  +				   sizeof(ADLIB_INSTR_MIDI_HACK)); + +			ptr[5]  += ch; +			ptr[28] += ch; +			ptr[92] += ch; +			 +			/* flags_1 */ +			ptr[30 + 0] = (instr[i * 16 + 3] >> 4) & 0xf; +			ptr[30 + 1] = instr[i * 16 + 3] & 0xf; +			 +			/* oplvl_1 */ +			ptr[30 + 2] = (instr[i * 16 + 4] >> 4) & 0xf; +			ptr[30 + 3] = instr[i * 16 + 4] & 0xf; +			 +			/* atdec_1 */ +			ptr[30 + 4] = ((~instr[i * 16 + 5]) >> 4) & 0xf; +			ptr[30 + 5] = (~instr[i * 16 + 5]) & 0xf; +			 +			/* sustrel_1 */ +			ptr[30 + 6] = ((~instr[i * 16 + 6]) >> 4) & 0xf; +			ptr[30 + 7] = (~instr[i * 16 + 6]) & 0xf; +			 +			/* waveform_1 */ +			ptr[30 + 8] = (instr[i * 16 + 7] >> 4) & 0xf; +			ptr[30 + 9] = instr[i * 16 + 7] & 0xf; +			 +			/* flags_2 */ +			ptr[30 + 10] = (instr[i * 16 + 8] >> 4) & 0xf; +			ptr[30 + 11] = instr[i * 16 + 8] & 0xf; +			 +			/* oplvl_2 */ +			ptr[30 + 12] = (instr[i * 16 + 9] >> 4) & 0xf; +			ptr[30 + 13] = instr[i * 16 + 9] & 0xf; +			 +			/* atdec_2 */ +			ptr[30 + 14] = ((~instr[i * 16 + 10]) >> 4) & 0xf; +			ptr[30 + 15] = (~instr[i * 16 + 10]) & 0xf; +			 +			/* sustrel_2 */ +			ptr[30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf; +			ptr[30 + 17] = (~instr[i * 16 + 11]) & 0xf; +			 +			/* waveform_2 */ +			ptr[30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf; +			ptr[30 + 19] = instr[i * 16 + 12] & 0xf; +			 +			/* feedback */ +			ptr[30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf; +			ptr[30 + 21] = instr[i * 16 + 2] & 0xf; +			ptr += sizeof(ADLIB_INSTR_MIDI_HACK); +		} -		/* sustrel_2 */ -		ptr[30 + 16] = ((~instr[i * 16 + 11]) >> 4) & 0xf; -		ptr[30 + 17] = (~instr[i * 16 + 11]) & 0xf; +		*ptr++ = 0;  // delay 0; -		/* waveform_2 */ -		ptr[30 + 18] = (instr[i * 16 + 12] >> 4) & 0xf; -		ptr[30 + 19] = instr[i * 16 + 12] & 0xf; +		// Now copy the actual music data  +		memcpy(ptr, track, size); +		ptr += size; -		/* feedback */ -		ptr[30 + 20] = (instr[i * 16 + 2] >> 4) & 0xf; -		ptr[30 + 21] = instr[i * 16 + 2] & 0xf; -		ptr += sizeof(ADLIB_INSTR_MIDI_HACK); -	} -	 -	*ptr++ = 0;  // delay 0; -	 -	// Now copy the actual music data  -	memcpy(ptr, track, size); -	ptr += size; -	 -	if (!play_once) { -		// The song is meant to be looped. We achieve this by inserting just -		// before the song end a jump to the song start. More precisely we abuse -		// a S&M sysex, "maybe_jump" to achieve this effect. We could also -		// use a set_loop sysex, but it's a bit longer, a little more complicated, -		// and has no advantage either. +		if (!play_once) { +			// The song is meant to be looped. We achieve this by inserting just +			// before the song end a jump to the song start. More precisely we abuse +			// a S&M sysex, "maybe_jump" to achieve this effect. We could also +			// use a set_loop sysex, but it's a bit longer, a little more complicated, +			// and has no advantage either. +			 +			// First, find the track end +			byte *end = ptr; +			ptr -= size; +			for (; ptr < end; ptr++) { +				if (*ptr == 0xff && *(ptr + 1) == 0x2f) +					break; +			} +			assert(ptr < end); +			 +			// Now insert the jump. The jump offset is measured in ticks, and  +			// each instrument definition spans 4 ticks... so we jump to tick +			// 8*4, although jumping to tick 0 would probably work fine, too. +			// Note: it's possible that some musics don't loop from the start... +			// in that case we'll have to figure out how the loop range is specified +			// and then how to handle it appropriately (if it's specified in +			// ticks, we are fine; but if it's a byte offset, it'll be nasty). +			const int jump_offset = 8 * 4; +			memcpy(ptr, "\xf0\x13\x7d\x30\00", 5); ptr += 5;	// maybe_jump +			memcpy(ptr, "\x00\x00", 2); ptr += 2;			// cmd -> 0 means always jump +			memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4;	// track -> there is only one track, 0 +			memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4;	// beat -> for now, 1 (first beat) +			// Ticks +			*ptr++ = (byte)((jump_offset >> 12) & 0x0F); +			*ptr++ = (byte)((jump_offset >> 8) & 0x0F); +			*ptr++ = (byte)((jump_offset >> 4) & 0x0F); +			*ptr++ = (byte)(jump_offset & 0x0F); +			memcpy(ptr, "\x00\xf7", 2); ptr += 2;	// sysex end marker +		} +		// Finally we reinsert the end of song sysex, just in case +		memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5; -		// First, find the track end -		byte *end = ptr; -		ptr -= size; -		for (; ptr < end; ptr++) { -			if (*ptr == 0xff && *(ptr + 1) == 0x2f) +		return 1; +	} + + +	/* This is a sfx resource.  First parse it quickly to find the parallel +	 * tracks. +	 */ +	byte current_instr[3][14]; +	int  current_note[3]; +	int track_time[3]; + +	int track_ctr = 0; +	byte chunk_type = 0; + +	for (i = 0; i < 3; i++) { +		track_time[i] = -1; +		current_note[i] = -1; +	} +	while (size > 0) { +		tracks[track_ctr] = src_ptr; +		track_time[track_ctr] = 0; +		track_ctr++; +		while (size > 0) { +			chunk_type = *(src_ptr); +			if (chunk_type == 1) { +				src_ptr += 15; +				size -= 15; +			} else if (chunk_type == 2) { +				src_ptr += 11; +				size -= 11; +			} else if (chunk_type == 0x80) { +				src_ptr ++; +				size --; +			} else {  				break; +			} +		} +		if (chunk_type == 0xff) +			break; +		src_ptr++; +	} +	 +	int curtime = 0; +	for (;;) { +		int mintime = -1; +		ch = -1; +		for (i = 0; i < 3; i++) { +			if (track_time[i] >= 0 &&  +				(mintime == -1 || mintime > track_time[i])) { +				mintime = track_time[i]; +				ch = i; +			} +		} +		if (mintime < 0) +			break; + +		src_ptr = tracks[ch]; +		chunk_type = *(src_ptr); + + +		if (current_note[ch] >= 0) { +			delay = mintime - curtime; +			curtime = mintime; +			if (delay > 0x7f) { +				if (delay > 0x3fff) { +					*ptr++ = (delay >> 14) | 0x80; +					delay &= 0x3fff; +				} +				*ptr++ = (delay >> 7) | 0x80; +				delay &= 0x7f; +			} +			*ptr++ = delay; +			*ptr++ = 0x80 + ch; // key off channel; +			*ptr++ = current_note[ch]; +			*ptr++ = 0; +			current_note[ch] = -1;  		} -		assert(ptr < end); -		// Now insert the jump. The jump offset is measured in ticks, and  -		// each instrument definition spans 4 ticks... so we jump to tick -		// 8*4, although jumping to tick 0 would probably work fine, too. -		// Note: it's possible that some musics don't loop from the start... -		// in that case we'll have to figure out how the loop range is specified -		// and then how to handle it appropriately (if it's specified in -		// ticks, we are fine; but if it's a byte offset, it'll be nasty). -		const int jump_offset = 8 * 4; -		memcpy(ptr, "\xf0\x13\x7d\x30\00", 5); ptr += 5;	// maybe_jump -		memcpy(ptr, "\x00\x00", 2); ptr += 2;			// cmd -> 0 means always jump -		memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4;	// track -> there is only one track, 0 -		memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4;	// beat -> for now, 1 (first beat) -		// Ticks -		*ptr++ = (byte)((jump_offset >> 12) & 0x0F); -		*ptr++ = (byte)((jump_offset >> 8) & 0x0F); -		*ptr++ = (byte)((jump_offset >> 4) & 0x0F); -		*ptr++ = (byte)(jump_offset & 0x0F); -		memcpy(ptr, "\x00\xf7", 2); ptr += 2;	// sysex end marker + +		switch (chunk_type) { +		case 1: +			/* Instrument definition */ +			memcpy(current_instr[ch], src_ptr+1, 14); +			src_ptr += 15; +			break; + +		case 2: +			/* tone/parammodulation */ +			memcpy(ptr, ADLIB_INSTR_MIDI_HACK,  +				   sizeof(ADLIB_INSTR_MIDI_HACK)); +			 +			ptr[5]  += ch; +			ptr[28] += ch; +			ptr[92] += ch; + +			/* flags_1 */ +			ptr[30 + 0] = (current_instr[ch][3] >> 4) & 0xf; +			ptr[30 + 1] = current_instr[ch][3] & 0xf; +			 +			/* oplvl_1 */ +			ptr[30 + 2] = (current_instr[ch][4] >> 4) & 0xf; +			ptr[30 + 3] = current_instr[ch][4] & 0xf; +			 +			/* atdec_1 */ +			ptr[30 + 4] = ((~current_instr[ch][5]) >> 4) & 0xf; +			ptr[30 + 5] = (~current_instr[ch][5]) & 0xf; +			 +			/* sustrel_1 */ +			ptr[30 + 6] = ((~current_instr[ch][6]) >> 4) & 0xf; +			ptr[30 + 7] = (~current_instr[ch][6]) & 0xf; +				 +			/* waveform_1 */ +			ptr[30 + 8] = (current_instr[ch][7] >> 4) & 0xf; +			ptr[30 + 9] = current_instr[ch][7] & 0xf; +				 +			/* flags_2 */ +			ptr[30 + 10] = (current_instr[ch][8] >> 4) & 0xf; +			ptr[30 + 11] = current_instr[ch][8] & 0xf; +			 +			/* oplvl_2 */ +			ptr[30 + 12] = ((current_instr[ch][9]) >> 4) & 0xf; +			ptr[30 + 13] = (current_instr[ch][9]) & 0xf; +			 +			/* atdec_2 */ +			ptr[30 + 14] = ((~current_instr[ch][10]) >> 4) & 0xf; +			ptr[30 + 15] = (~current_instr[ch][10]) & 0xf; +			 +			/* sustrel_2 */ +			ptr[30 + 16] = ((~current_instr[ch][11]) >> 4) & 0xf; +			ptr[30 + 17] = (~current_instr[ch][11]) & 0xf; +			 +			/* waveform_2 */ +			ptr[30 + 18] = (current_instr[ch][12] >> 4) & 0xf; +			ptr[30 + 19] = current_instr[ch][12] & 0xf; +			 +			/* feedback */ +			ptr[30 + 20] = (current_instr[ch][2] >> 4) & 0xf; +			ptr[30 + 21] = current_instr[ch][2] & 0xf; + +			delay = mintime - curtime; +			curtime = mintime; + + +			 +			{ +				delay = convert_extraflags(ptr + 30 + 22, src_ptr + 1); +				delay2 = convert_extraflags(ptr + 30 + 40, src_ptr + 6); +				debug(4, "delays: %d / %d", delay, delay2); +				if (delay2 >= 0 && delay2 < delay) +					delay = delay2; +				if (delay == -1) +					delay = 0; +			} +							 +			/* duration */ +			ptr[30 + 58] = 0; // ((delay * 17 / 63) >> 4) & 0xf; +			ptr[30 + 59] = 0; // (delay * 17 / 63) & 0xf; +				 +			ptr += sizeof(ADLIB_INSTR_MIDI_HACK); + +			olddelay = mintime - curtime; +			curtime = mintime; +			if (olddelay > 0x7f) { +				if (olddelay > 0x3fff) { +					*ptr++ = (olddelay >> 14) | 0x80; +					olddelay &= 0x3fff; +				} +				*ptr++ = (olddelay >> 7) | 0x80; +				olddelay &= 0x7f; +			} +			*ptr++ = olddelay; + + +			/* FIXME:  delay factor found by try and error */ +			delay = (delay + 1) * 240 / 13; +			 +			{ +				int freq = ((current_instr[ch][1] & 3) << 8) +					| current_instr[ch][0]; +				freq <<= ((current_instr[ch][1] >> 2) & 7) + 1; +				int note = -11; +				while (freq >= 0x100) { +					note += 12; +					freq >>= 1; +				} +				debug(4, "Freq: %d (%x) Note: %d", freq, freq, note); +				if (freq < 0x80) +					note = 0; +				else +					note += freq2note[freq - 0x80]; + +				debug(4, "Note: %d", note); +				if (note < 0) +				    note = 0; +				else if (note > 127) +				    note = 127; +				 +				// Insert a note on event  +				*ptr++ = 0x90 + ch; // key on channel +				*ptr++ = note; +				*ptr++ = 63; +				current_note[ch] = note; +				track_time[ch] = curtime + delay;				 +			} +			src_ptr += 11; +			break; +			 +		case 0x80: +			track_time[ch] = -1; +			src_ptr ++; +			break; +			 +		default: +			track_time[ch] = -1; +		} +		tracks[ch] = src_ptr;  	} -	// Finally we reinsert the end of song sysex, just in case + +	/* insert end of song sysex */  	memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5; -	 +  	return 1;  } diff --git a/scumm/scummvm.cpp b/scumm/scummvm.cpp index 0a75b46ba5..3413d8dcc5 100644 --- a/scumm/scummvm.cpp +++ b/scumm/scummvm.cpp @@ -619,7 +619,7 @@ Scumm::Scumm (GameDetector *detector, OSystem *syst)  		_imuseDigital = new IMuseDigital(this);  	} else if ((_features & GF_AMIGA) && (_features & GF_OLD_BUNDLE)) {  		_playerV2 = NULL; -	} else if (_features & GF_OLD_BUNDLE) { +	} else if (_version <= 2) {  		if ((_version == 1) && (_gameId == GID_MANIAC))  			_playerV2 = NULL;  		else diff --git a/scumm/sound.cpp b/scumm/sound.cpp index 3ea0aea0be..39ca11053a 100644 --- a/scumm/sound.cpp +++ b/scumm/sound.cpp @@ -512,7 +512,7 @@ void Sound::playSound(int soundID) {  		return;  	} -	if (_scumm->_features & GF_OLD_BUNDLE) { +	if (_scumm->_version <= 2) {  		//TODO: support maniac v1 sounds  		if ((_scumm->_version == 1) && (_scumm->_gameId == GID_MANIAC))   			return;  | 
